Using SD Card and conflicts with GPIO lines
Started by CaptUnderpants, Dec 13 2010 06:04 PM
7 replies to this topic
#1
Posted 13 December 2010 - 06:04 PM
I'm wondering if there is a conflict with using the SD Card reader/writer and using any of the gpio lines? Reason I ask is that I notice that if I write anything to the card (via streamwriter) I cannot use Pins.GPIO_PIN_D2 as an OutputPort.
What I did was define d0->d7 as output and attached leds. Then I just cycle thru them turning them on and of like the blinky example(oOoOoO flashy lights). However in the program there is also a log function where it will log events to a text file on the sd card. If I enable the log function ( create the StreanWriter object, write to a file, close/dispose of the object ) Pins.GPIO_PIN_D2 ceases to work. Is there something else that has to be touched after the file write? Also, if I use the onboard ethernet will there be any issues like this?
Can anyone point me in the right direction?
#2
Posted 13 December 2010 - 06:16 PM
Hi CaptUnderpants,
Welcome to the Netduino community.
You should be able to use the MicroSD card feature and simultaneously use all of the digital/analog pins. The MicroSD card is actually on a complete separate SPI bus using completely separate pins.
Could you post a small snippet of code which demonstrates the issue you're having? If we can reproduce the issue here, we should be able to hunt down the issue quickly...
Chris
#3
Posted 13 December 2010 - 06:41 PM
Sure. Here is something that demos the point:
~~~
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Blinky
{
public class Program
{
public static void Main()
{
DeviceInfo deviceInfo = new DeviceInfo();
//Log log = new Log();
int i = 0;
while (true)
{
deviceInfo.a.Write(true);
Thread.Sleep(250);
deviceInfo.a.Write(false);
Thread.Sleep(250);
deviceInfo.b.Write(true);
Thread.Sleep(250);
deviceInfo.b.Write(false);
Thread.Sleep(250);
deviceInfo.c.Write(true);
Thread.Sleep(250);
deviceInfo.c.Write(false);
Thread.Sleep(250);
deviceInfo.d.Write(true);
Thread.Sleep(250);
deviceInfo.d.Write(false);
Thread.Sleep(250);
deviceInfo.e.Write(true);
Thread.Sleep(250);
deviceInfo.e.Write(false);
Thread.Sleep(250);
deviceInfo.f.Write(true);
Thread.Sleep(250);
deviceInfo.f.Write(false);
Thread.Sleep(250);
deviceInfo.g.Write(true);
Thread.Sleep(250);
deviceInfo.g.Write(false);
Thread.Sleep(250);
deviceInfo.h.Write(true);
Thread.Sleep(250);
deviceInfo.h.Write(false);
Thread.Sleep(250);
//log.Write("thru the loop " + i++.ToString() + " times", "INFO");
}
}
}
public class DeviceInfo
{
static Cpu.Pin[] dPins = {Pins.GPIO_PIN_D0, Pins.GPIO_PIN_D1, Pins.GPIO_PIN_D2, Pins.GPIO_PIN_D3,
Pins.GPIO_PIN_D4, Pins.GPIO_PIN_D5, Pins.GPIO_PIN_D6, Pins.GPIO_PIN_D7,
Pins.GPIO_PIN_D8, Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D10, Pins.GPIO_PIN_D11,
Pins.GPIO_PIN_D12, Pins.GPIO_PIN_D13};
//OutputPort a = new OutputPort(dPins[0], false);
public OutputPort a = new OutputPort(dPins[0], false);
public OutputPort b = new OutputPort(dPins[1], false);
public OutputPort c = new OutputPort(dPins[2], false);
public OutputPort d = new OutputPort(dPins[3], false);
public OutputPort e = new OutputPort(dPins[4], false);
public OutputPort f = new OutputPort(dPins[5], false);
public OutputPort g = new OutputPort(dPins[6], false);
public OutputPort h = new OutputPort(dPins[7], false);
}
public class Log
{
private string backupPath = @"\SD\Logs";
private bool _isErr = true;
private bool _isInfo = true;
public bool isErr
{
get { return _isErr; }
set { _isErr = value; }
}
public bool isInfo
{
get { return _isInfo; }
set { _isInfo = value; }
}
public Log()
{
DateTime Now = DateTime.Now;
if (Directory.Exists(@"\SD"))
{
if (!Directory.Exists(backupPath))
Directory.CreateDirectory(backupPath);
backupPath = Path.Combine(backupPath, "blinkyLOG" + "." + Now.ToString("yy-MM-dd") + ".txt");
}
}
public void Write(string message, string destination)
{
Thread logThread = new Thread(delegate() { WriteToFile(message, destination); });
logThread.Start();
}
private void WriteToFile(String message, string destination)
{
DateTime Now = DateTime.Now;
if ((destination == "ERR") && _isErr)
{
WriteLogLine(Now.ToString("yy'-'MM'-'dd':'hh':'mm':'ss'.'fff '->'") + destination + " - " + message);
}
if ((destination == "INFO") && _isInfo)
{
WriteLogLine(Now.ToString("yy'-'MM'-'dd':'hh':'mm':'ss'.'fff '->'") + destination + " - " + message);
}
}
private void WriteLogLine(string payload)
{
StreamWriter sw = new StreamWriter(backupPath, true);
if (sw == null)
{
Debug.Print("can't find log file");
Debug.Print(payload);
}
else
{
try
{
sw.WriteLine(payload);
}
catch (Exception ex)
{
Debug.Print(ex.Message);
}
}
sw.Close();
sw.Dispose();
}
}
}
~~~
I have the log creation and log write commented out and all 8 leds light up. take the comments out and # 2 will not light....
Have I missed something simple??
#4
Posted 14 December 2010 - 04:45 AM
Hello,
I have been able to replicate your problem. I have also been able to isolate it somewhat.
The problem seems to be related, not to SD operations per se, but to certain directory operations on the SD card. This seems like a real bug to me.As a hacky little workaround, you can get your program to work if you do all of your directory operations prior to allocating the pins. In particular, you should swap these two lines so that the "Log" one comes first:
Below is a video of the problem in action, and after that, the code I used to isolate your problem. It runs normally for the first three iterations (j=0,1,2) and then begins to demonstrate the problem.
http://www.youtube.com/watch?v=8Un0LhKg9tc
I have been able to replicate your problem. I have also been able to isolate it somewhat.
The problem seems to be related, not to SD operations per se, but to certain directory operations on the SD card. This seems like a real bug to me.
Log log = new Log(); //make this one go first so the directory operations run first DeviceInfo deviceInfo = new DeviceInfo();
Below is a video of the problem in action, and after that, the code I used to isolate your problem. It runs normally for the first three iterations (j=0,1,2) and then begins to demonstrate the problem.
http://www.youtube.com/watch?v=8Un0LhKg9tc
using System.Threading; using Microsoft.SPOT.Hardware; using System.IO; using SecretLabs.NETMF.Hardware.Netduino; namespace Blinky2 { public class Program { public static void Main() { var dPins=new[] { Pins.GPIO_PIN_D0, Pins.GPIO_PIN_D1, Pins.GPIO_PIN_D2, Pins.GPIO_PIN_D3, Pins.GPIO_PIN_D4, Pins.GPIO_PIN_D5, Pins.GPIO_PIN_D6, Pins.GPIO_PIN_D7, }; var outputPorts=new OutputPort[dPins.Length]; for(var i=0; i<dPins.Length; ++i) { outputPorts[i]=new OutputPort(dPins[i], false); } for(var j=0; j<100; ++j) { if(j==3) { var dontCare=Directory.Exists(@"\SD\Logs"); } for(var i=0; i<dPins.Length; ++i) { for(var onOff=0; onOff<2; ++onOff) { outputPorts[i].Write(onOff==0); Thread.Sleep(150); } } } } } }
#5
Posted 14 December 2010 - 05:46 AM
Correction: my "workaround" doesn't work. It does indeed seem that LED 2 gets messed up every time you access the SD card, not just via Directory.* calls.
#6
Posted 15 December 2010 - 01:08 AM
Correction: my "workaround" doesn't work. It does indeed seem that LED 2 gets messed up every time you access the SD card, not just via Directory.* calls.
Ok then, glad to know it was just me. I wonder if this is hardware or something else. Hmmmmm....more reading is needed.
#7
Posted 01 January 2011 - 07:11 AM
Update: this has been fixed in the v4.1.1 alpha 4 firmware.
#8
Posted 01 January 2011 - 05:19 PM
fantastic! Thanks
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users