Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.

ShVerni

Member Since 28 Dec 2011
Offline Last Active Private
-----

#64288 More Digital I/O

Posted by ShVerni on 12 October 2015 - 04:01 PM

I'm afraid I don't, but here's the hookups you need for the MCP23S08:

 

MCP23S08       Netduino

SCK (1)     -->  13 (SPCK)

SI (2)         -->  11 (MOSI)

SO (3)       -->  12 (MISO)

A1 (4)        -->  GND

A0 (5)        -->  GND

RESET (6) -->  3.3V

CS (7)        --> 10

INT (8) Not connected (optional)

VSS (9)      --> GND

VDD (18)   --> 3.3V

 

 

The MCP23S17 is much the same (except the pin numbers are different) but it has an additional address pin A2 that is connected to ground. The address pins (A0, A1) define the address of the chip, and are used when initializing the chip like so:

// Use "new MCP23S08(CS pin, address)" to initialize an expander 
MCP23S08 expander = new MCP23S08(Pins.GPIO_PIN_D10, 0x00);

When A0 and A1 are both connected to ground, the address is 0x00. Here's a table of addresses for the MCP23S08:

 

A0       A1      Address

GND   GND   0x00

3.3V   GND   0x01

GND   3.3V   0x02

3.3V   3.3V   0x03




#60783 Simple switch detection circuit - don't want to fry board

Posted by ShVerni on 23 November 2014 - 05:47 PM

Hi Rob,

 

You're perfectly on point that your circuit it will work just fine. The Netduio's digital pins are 5V tolerant even though they operate at 3.3V. That is to say, they output 3.3V signals, but will accept 5V or 3.3V signals as input. That said, it certainly wouldn't hurt to go with 3.3V, it will even save a miniscule amount of power (though really, not enough be worthwhile is all but the most power sensitive applications). As a word of caution: the Netduino's analog pins, when not operating as digital pins, are NOT 5V tolerant, and using a 5V signal could damage them. To be safe, I try to only use 3.3V signals with the analog pins.

 

As a point of nomenclature, a resister tied to ground is a pull-down (down to 0) and a resistor tied to VCC is a pull-up.

 

Good luck!




#59860 Question comparing Netduino vs Arduino

Posted by ShVerni on 22 August 2014 - 06:06 PM

I'm certainly no expert, but I have done a bit of work on both Arduino and Netduino, even trying to get them to work together. Here is a brief overview of my impressions of the systems, their strengths and weaknesses.

 

I've, personally, found that Arduinos are much easier to use for specific tasks. That is to say, if I want to have a microcontroller do one, maybe two, things (act as a doorbell, generate random text sentences when a button is pressed, create an optotheremin etc...) Arduinos are often much simpler and faster to get up and running, or at least no more difficult. This is largely do to the fact that, because of their age and popularity, there are vast quantities of libraries (yes, those are very similar to including additional .cs files) and other code examples out there on the Internet where very talented people have already worked out most of the details.

 

Since Arduinos don't have the overhead or quirks of the .NETMF, they can more easily do things that require fast, precise timing (see the WS2812 LEDs), and they seem to require less boilerplate code to setup since there's no framework to deal with (although that's really a matter of where you look in the code, since .NETMF also provides some great shortcuts).

 

Where I find the Netduino really shines is for more complicated tasks. Since an Arduino runs everything in a single main loop, to have multiple inputs (say, serial inputs, buttons presses, and analogue sensors) requires creating a state machine or other complex system, and Arduinos are generally limited to only two hardware interrupt ports. Thanks to Netduino's interrupts and multithreading, it's much easier to keep track of all the inputs and outputs for complicated projects.

 

For instance, while I likely could have used an Arduino for setting up my garden project, I think the Netduino made organizing all the lights, and pumps, and Bluetooth commands, and SD card read/writes, and moisture sensors so much easier. I would have gotten lost trying to set up all the conditional options with an Arduino. Now, those more skilled in working with Arduino than myself would likely be able to pull it off without too much trouble, but I still prefer the modular organization, and other nifty features, offered by the .NETMF and VisualStudio.

 

I've always liked the idea of playing to the strengths of each system by using a Netduino as a command and control center using serial to send instructions to Arduinos which are set up to do specific things, but that's just me. In short, as an amateur in this field, my experience has been that Arduinos are super easy to get up and running for simple tasks, but for more complicated projects, or things without existing Arduino libraries, I find the Netduino easier to work with.

 

That's just my long-winded opinion, but I hope it helps in some way.




#58187 How do I pause a while loop using the onboard button?

Posted by ShVerni on 17 May 2014 - 01:14 AM

Hello,
 
If you'd like to do everything in one loop, this seems like the easiest solution:

public class Program
    {
        private static bool _blink = true;
        private static OutputPort _led = new OutputPort(Pins.ONBOARD_LED, false);
        private static InputPort _button = new InputPort(Pins.ONBOARD_BTN, false, Port.ResistorMode.Disabled);
        public static void Main()
        {
            while(true)
            {
                if (_button.Read())
                    _blink = !_blink;
                if (_blink)
                    _led.Write(!_led.Read()); //Sets the LED to the opposite of its current state
                Thread.Sleep(250);
            }
        }
    }

Now obviously there are some downsides to this approach, mainly that the button is only polled every 250 ms, so the button may not be very responsive and could be "missed" as you noticed.
 
Now, the idea you had of using two loops in different threads could look something like this:

public class Program
    {
        private static bool _blink = true;
        private static OutputPort _led = new OutputPort(Pins.ONBOARD_LED, false);
        private static InputPort _button = new InputPort(Pins.ONBOARD_BTN, false, Port.ResistorMode.Disabled);
        public static void Main()
        {
            //Start button polling thread
            new Thread(buttonLoop).Start();

            while(true)
            {
                if (_blink)
                    _led.Write(!_led.Read());
                Thread.Sleep(250);
            }
        }

        private static void buttonLoop()
        {
            while (true)
            {
                if (_button.Read())
                    _blink = !_blink;
                Thread.Sleep(50);
            }
        }
    }

You could try tuning the Thread.Sleep call in the buttonLoop to get the responsiveness you'd like, but there's still a lot of wasted overhead looping through things and polling the button. Plus, there's still a chance of "missing" the button press or reading too many presses.
 
This brings us to the event driven method, which is probably the most elegant solution, and uses an interrupt port for the button:

public class Program
    {
        private static bool _blink = true;
        private static OutputPort _led = new OutputPort(Pins.ONBOARD_LED, false);
        private static InterruptPort _button = new InterruptPort(Pins.ONBOARD_BTN, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeHigh);
        public static void Main()
        {
            //Attach the interrupt event
            _button.OnInterrupt += _button_OnInterrupt;

            while(true)
            {
                if (_blink)
                    _led.Write(!_led.Read());
                Thread.Sleep(250);
            }
        }

        static void _button_OnInterrupt(uint port, uint status, DateTime time)
        {
            Debug.Print("Button pushed");
            _blink = !_blink;
        }
    }

I should make a note to notice this parameter in the InterruptPort: Port.InterruptMode.InterruptEdgeHigh. That sets the interrupt to trigger whenever it sees a "high" logic value, essentially when the button would be read as True. I actually forget if the onboard_btn when pressed gives a "high" or "low" logic signal. If that doesn't work, try changing that parameter to Port.InterruptMode.InterruptEdgeLow. This also applies to all the times I called _button.Read() in my other examples, if things aren't working right you might need to change them to !_button.Read().

 

Also, if you use the interrupt method, you'll probably notice a lot of "bounce", which is the button quickly triggering multiple times as you press it, so you'll have to lean a bit about debouncing, and this post is a good place to start:
 
http://forums.netdui...upt/#entry55487

 

That thread also has some good infomation on buttons and interrupts in general. There are definitely other ways to do this sort of thing, but this should be a good start.

 

Good luck!




#57676 Random Number Generation

Posted by ShVerni on 22 April 2014 - 03:48 AM

Hello,

 

You could try seeding the radom object using a read from a unconnected analog input, which is usually pretty random. Something along the lines of:

AnalogInput _seed = new AnalogInput(Cpu.AnalogChannel.ANALOG_0);
Random _random = new Random(_seed.ReadRaw());
_seed.Dispose();

You don't have to dispose of the analog channel, but you shold leave it unconnected so the value will be "floating".

 

You could also use a larger MAX for your random function, and then map that value onto the range you want, using a map funtion like this:

 

http://stackoverflow...-map-in-arduino

 

Hope that helps!




#56659 Automated Urban Garden

Posted by ShVerni on 05 March 2014 - 09:05 PM

Hello and welcome!

 

It's good to meet another NYC urban gardener! Providing light to your plants is definitely a good place to start, though I'd be interested to hear about where you end up taking your project. I have a complete parts list in the GoogleDoc I linked to in the first post which should give you an idea about hardware, but if you have any questions just let me know.

 

Good luck!




#56615 433MHz / 2.4GHz communications with Netduino/Netduino Plus

Posted by ShVerni on 04 March 2014 - 05:50 AM

Hello,

 

I recently got some nRF24L01+ working between a Netduino and some Arduinos using the following libraries:

 

http://maniacbug.github.io/RF24/

 

http://nrf24l01.codeplex.com/

 

I had a lot of trouble until I realized that the CodePlex Netduino driver writes the Most Significant Byte first, when it should--or at least the Arduino library expects--the Least Significant Byte to be written first. A few quick hacks to reverse the byte order on things like the addresses and data being sent/received and everything seems to be working smoothly. So to anyone who wants to use these with the Arduino library, be sure to reverse the byte order.




#55705 Analog input resolution &

Posted by ShVerni on 28 January 2014 - 04:51 PM

As I understand it, the original Netduinos had 10 bit ADCs, while the Netduino 2 and the Netduino Plus 2 (and maybe the Netduino Go?) have a 12 bit ADC.

 

If you're worried about cross platform compatibility, you should use the Microsoft AnalogInput class, the Read method for which returns a number between 0 and 1 based on the reading, essentially a percentage of the maximum voltage.

 

To use the Microsoft class you need to use AnalogChannels not Pins:

AnalogInput pot1 = new  AnalogInput(AnalogChannels.ANALOG_PIN_A1);

Check out this thread for more details:

http://forums.netdui...etduino-plus-2/

 

Hope that helps!




#55677 Automated Urban Garden

Posted by ShVerni on 27 January 2014 - 05:05 AM

Hello,
 
I've finally come to a reasonably advanced stage on a project I've been wanting to do for a while: An automated urban garden. I've always liked the idea of houseplants, but never had the skill or the attention to detail to keep said plants alive. This seemed like the perfect opportunity to outsource the care of the plants to a Netduino.
 
Behold!
 

7.Assembled(small).jpg

 
At this point, the garden will automatically water plants, optionally using a soil moisture sensor. The reservoir that holds the water will alert you when it needs refilling. It also shines a grow lamp on the plants in a way that simulates the change in sunlight over the year. The whole thing can be controlled via Bluetooth and an Android application.
 
I've documented my experience, and most of the garden, here:
https://docs.google....mebhKZtPqfKpsQ/
 
And I've included all the code, and lots of other things, here:
https://drive.google...eE0&usp=sharing
 
I've also attached the code to this post.
 
It's not a hundred-percent finished yet, and is a bit crude, but hopefully I'll have some lovely flowers soon!
Attached File  Garden.zip   13.6KB   46 downloads




#55487 Momentary button and interrupt

Posted by ShVerni on 19 January 2014 - 04:21 PM

Hi again Nicolai, and welcome to the wonderful world of bounce!
 
What you're experiencing is perfectly normal, and is called bounce. We like to think that buttons behave ideally, but that's far from the truth. I won't go into too much detail, since there are many excellent articles on bounce out there already. In short, when you push a button the physical contacts will actually bounce off each other a bit, somewhere on the micro to millisecond scale, before the button settles into a proper "on" or "off" position. So as it bounces it will appear to the microcontroller to be flipping on and off rapidly.

 

Here are two great posts on debouncing with the Netduino, which I'll summarize a bit below:
http://forums.netdui...input-debounce/
http://forums.netdui...ure/#entry55151
 
There are two ways to deal with bounce: Hardware debouncers and software debouncers. Hardware debouncers are better since they prevent the noise from even reaching the microcontroller, but they require additional hardware, maybe some math, and are more complicated. Software debouncing is easier to do, but will require the microcontroller to do some work, so it may still affect performance.
 
The simplest hardware debouncer (and certainly not the best one) is a capacitor and resistor that you place across your switch. So you'd connect the positive terminal of the capacitor to the positive side of the switch (in this case the GPIO) and the negative side, through a resistor, to the negative part of your switch (in this case, ground). The values of the capacitor and the resistor will affect how much debouncing you get. I'm not familiar will all the math involved, but I'm sure you can find someone else who's laid out the equations.
 
Here's how you'd implement a software debouncer for the above code:

 public class Program
    {
        private static InterruptPort button = new InterruptPort(Pins.GPIO_PIN_D0, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
        private static OutputPort LED = new OutputPort(Pins.GPIO_PIN_D1, false);
        private static DateTime lastEvent = DateTime.Now;
        public static void Main()
        {
            button.OnInterrupt += button_OnInterrupt;
            Thread.Sleep(Timeout.Infinite);
        }

        static void button_OnInterrupt(uint port, uint status, DateTime time)
        {
            //Check to see if the last event was more than 500 milliseconds before this trigger			    
            if (time.AddMilliseconds(-500) > lastEvent)
            {
                //Update when the last event was (we subtracted 500 milliseconds before, so now we need to add them back)
                lastEvent = time.AddMilliseconds(500);
                if (status == 0)
                    LED.Write(true);
                else
                    LED.Write(false);
            }
        }
    }

You'll notice the event will still fire, but now it won't do anything unless the time between events is greater than 500 milliseconds (or whatever you set this too). This is not the most elegant debouncer out there, it's just a quick one to show how it can be done, and there are many other examples (including the two links I provided) that you can use.
 
Using a software debouncer you probably won't notice any difference, since the event is still triggering and the LED would be blinking too fast for you to see when bouncing. But if your event did something, like adding to a counter, this would help by discarding events triggered by bouncing.
 
By the way, using the loop method instead of an interrupt won't cause this problem since the loop polls the button preiodically. However, interrupts are certainly more elegant, responsive, and very useful, so it's good to learn debouncing.
 
Good luck!




#55296 How to find/set the Serial Port on Netduino Plus 2?

Posted by ShVerni on 11 January 2014 - 03:28 AM

Hello,

 

If you look here:

 

http://netduino.com/...plus2/specs.htm

 

you'll see UART 1, UART 2, etc... with RX and TX. These refer to COM1 receive and transmit, COM2 receive and transmit, and so on. In short:

 

COM1 RX-TX: Pins 0-1,

COM2 RX-TX: Pins 2-3,

COM3 RX-TX: Pins 7-8,

COM4 RX-TX: SDA-SCL

 

I hope that helps!




#54962 Getting Started with Interrupts

Posted by ShVerni on 28 December 2013 - 07:40 AM

Looks like Chris beat me to the answer (that'll teach me to take so long composing), but if you're interested in the nitty-gritty of interrupts, this post is pretty excellent:

 

http://www.tinyclr.i...management.aspx




#54843 Running code loaded into an Micro SD card on a Netduino

Posted by ShVerni on 23 December 2013 - 07:43 PM

Hi Milt,

 

Unfortunately, running a program from an SD card is not as simple as plugging in the SD card. These are two excellent posts regarding how to do it:

 

http://fabienroyer.w...ith-a-netduino/

 

http://forums.netdui...ot-implemented/

 

In short, you compile a program you want to run, and then copy the portable executable (PE) file to the SD card, then you load that program from the SD card with another program you deploy to the Netduino in the usual way,

 

For example, if you had a program on your SD card called foo.pe, with a namespace of foo, a class called Program and with a method called Start() in that class, this would launch it and pass an object array of arguments to the method:

string test = "Test";
int bar = 10;
object[][] args = { new object[] { test, bar } };
using (FileStream assmfile = new FileStream(@"SDfoo.pe", FileMode.Open, FileAccess.Read, FileShare.None))
{     
     byte[] assmbytes = new byte[(int)assmfile.Length];    
     assmfile.Read(assmbytes, 0, (int)assmfile.Length);     
     var assm = Assembly.Load(assmbytes);
     var type = assm.GetType("foo.Program");
     var obj = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(assm.FullName, type.FullName);
     MethodInfo mi = type.GetMethod("Start");
     mi.Invoke(obj, args);
}

If you don't want to pass any arguments, you can make this alteration:

mi.Invoke(obj, null);

Additionally, you'll need to add these includes:

using System.Diagnostics;
using System.Reflection;
using System.IO;
using SecretLabs.NETMF.IO;

On the other side, the program foo would look something like this:

namespace foo
{
    public class Program
    {
        public static void Main()
        {
            // This intentionally left blank
        }
        public static void Start(object[] args)
        {
            string test = (string)args[0];
            int bar = (int)args[1];
            Debug.Print("Test=" + test + " bar=" + bar.ToString());
        }
    }
}

I've found this to be a very touchy bit of code, so it can take a while to get everything to work properly. Best of luck!




#51183 Web Based IR Remote

Posted by ShVerni on 08 July 2013 - 02:24 AM

Hello all,   Unfortunately, I was unable to finish this project last summer before it became too cool to need it. However, with the return of the heatwave to NYC, I decided to dust of my old code, fix it up, and finish this project! I've replaced the TMP36 with the HIH6130 temperature/humidity sensor, and used a modified version of the HTTPLibrary V3. I've upgraded the web server to allow the addition and removal of passwords though the web interface so I can grant guests access to the control system, as well as adding some watchdogs to restart the system if the server thread hangs. I also have the server cache a few settings on the SD card so that those settings will survive a reboot or power loss.   I added a photoresistor taped over the power LED of the AC unit so I could check if it was on and make sure the IR commands were being followed. I've found that the IR commands have somewhere around an 80% success rate, so getting feedback from the photoresistors was necessary to ensure everything went smoothly. I've attached all the code for this project below, although it's not well documented and still pretty crude, so be warned. I've also included all the HTML/JavaScript files.

 

I also attached a photo of the system all hooked up, though I still need to build an enclosure for the Netduino.   Thanks again for all the help, it's nice to finally have this project finished and working great!

Attached File  IRWebServer.zip   51.05KB   29 downloads

Attached File  ServerSetup.JPG   149.04KB   25 downloads


  • HCB likes this


#51054 SD Card and other SPI devices

Posted by ShVerni on 03 July 2013 - 06:40 PM

Hi Dennis,

 

It's actually relatively easy to use, really, as many SPI devices as you want. From a hardware perspective, you of course need to hook them all up to the correct MISO, MOSI, and SCLK pins. After that, you need to hook up each device to its own CS pin.

 

The important thing is to give each deivce it's own configuration, and then swap out the configurations of the devices. This wiki page has some good examples: http://wiki.netduino.com/SPI.ashx

 

I could be mistaken, but when using an SD card, you don't need to swap the configuration, as the framework does that for you whenever you try to access the SD card, but you will need to swap out the configuration for using other attached devices, like so:

class Program
{
        private static SPI spi;

        public static void Main()
        {
            StorageDevice.MountSD("SD", SPI.SPI_module.SPI1, Pins.GPIO_PIN_D10, Pins.GPIO_NONE);
            
            //Use this to initialize the SPI module, the conif doesn't really matter since we'll change it anyway
            SPI.Configuration config = new SPI.Configuration(
                SPI_mod: SPI.SPI_module.SPI1,
                ChipSelect_Port: Pins.GPIO_NONE,
                ChipSelect_ActiveState: false,
                ChipSelect_SetupTime: 0,
                ChipSelect_HoldTime: 0,
                Clock_IdleState: false,
                Clock_Edge: true,
                Clock_RateKHz: 1000);
            spi = new SPI(config);

            //Test the SD card
            using (StreamWriter sw = new StreamWriter(@"SDTest.txt", true))
            {
                sw.WriteLine("This is test one");
            }

            //Write to device one
            writeByteToOne(new byte[] { 255 });

            //Write to device two
            writeByteToTwo(new byte[] { 128 });

            //Test the SD card again
            using (StreamWriter sw = new StreamWriter(@"SDTest.txt", true))
            {
                sw.WriteLine("This is test two");
            }
        }

        private static void writeByteToOne(byte[] data)
        {
            //Set the configuration of device one
            SPI.Configuration config = new SPI.Configuration(
                SPI_mod: SPI.SPI_module.SPI1,
                ChipSelect_Port: Pins.GPIO_PIN_D0,
                ChipSelect_ActiveState: false,
                ChipSelect_SetupTime: 0,
                ChipSelect_HoldTime: 0,
                Clock_IdleState: false,
                Clock_Edge: true,
                Clock_RateKHz: 40000);

            //Set the config of the SPI module
            spi.Config = config;
            spi.Write(data);
        }        

        private static void writeByteToTwo(byte[] data)
        {
            //Set the configuration of device two
            SPI.Configuration config = new SPI.Configuration(
                SPI_mod: SPI.SPI_module.SPI1,
                ChipSelect_Port: Pins.GPIO_PIN_D1,
                ChipSelect_ActiveState: false,
                ChipSelect_SetupTime: 0,
                ChipSelect_HoldTime: 0,
                Clock_IdleState: false,
                Clock_Edge: true,
                Clock_RateKHz: 5000);

            //Set the config of the SPI module
            spi.Config = config;
            spi.Write(data);
        }
        //Add more devices if you want. Better, put each device in its own class.
}

This is just a quick and dirty unoptomized example, and assumes the CS pin of the SD card is D10, and that you're not using the CD pin. You could improve things by putting each device it its own class with a configuration that gets swapped in whenever you call a write or read from the device class, for instance.

 

Also, the venerable Stefan has created a MultiSPI class as part of his excellent .NET ToolBox, which you can find here: http://netmftoolbox....rdware.MultiSPI

 

I hope that helps!






home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.