Saturday, December 31, 2016

External Keypad For Windows controlled by .NET code


Overview

This keypad below is very cheap, so i bought 2 just to try them with Nusbio.net. Though it is a very simple device, it is not easy to explain how this work and moreover the theory behind the source code.
It is a little bit tricky and requires to understand sourcing and sinking current.
If you do not get it right away it is normal.
But you should be able to understand the basic idea just by reading the source code and my comments below.
With an Arduino you will find tutorial and library already made, but for .NET and Nusbio I had to write my own class (that is part of the open source samples that come with the Nusbio device).


First

There are plenty of tutorial on the internet about it, here is one I like the most to read first Arduino with Keypad Tutorial

Here is my take on it for software developers.

We have a grid of 4 rows and 3 colums. Each rows and columns connect to each other when one of the 12 buttons is pressed. We are going use 4+3 == 7 GPIO pins and monitor the connection between rows and the columns.

From a software point of view we have to constantly polled the state of the 12 buttons.

Initialization


The 4 GPIO pins connected to the 4 rows are open in input pull up mode, simply said this mean that the state of the pin is Readable (Input) and default state value is HIGH (AKA 1 or 5 Volts) and could be come a LOW (AKA 0 or 0 Volt) if there is a path to ground.
The 3 GPIO pins connected to the 3 columns are open in output mode, (the state can be set to HIGH or LOW programmatically) and set first to HIGH (1).
In this state nothing will happen, no current flow even if one button is pressed because current only flow from HIGH to LOW.

For one specific column if one button is pressed a connection is made between the column and the row and the state of the row will change from HIGH to LOW.

In a function called constantly we going one at time 
  1. Change the state of one the column GPIO pin to LOW (so now we know the column)
  2. Then we are going to read the state of the 4 GPIO pins rows one after the other,
    if the state is HIGH the button matching the current column and row is not pressed,
    but if the state is LOW, then this mean there is a connection because the button is pressed and the current flowing from HIGH to LOW changing the state of the row GPIO pins (which is readable, because it was open as input)

Source Code

Initialization

private List _gpioRow;
private List _gpioCol;
private Nusbio           _nusbio;
private List<List<char>> _keys;

private void Init()
{
    for (var r = 0; r < this._gpioRow.Count; r++)
    {
        this._nusbio.SetPinMode(this._gpioRow[r], PinMode.Input);
    }
    for (var c = 0; c < this._gpioCol.Count; c++)
    {
        this._nusbio.SetPinMode(this._gpioCol[c], PinMode.Output);
        _nusbio.GPIOS[this._gpioCol[c]].High();
    }
}

Check() function


public KeypadPressedInfo Check()
{
    KeypadPressedInfo rr = null;
    var found            = false;
    for (var c = 0; c < this._gpioCol.Count; c++)
    {
        _nusbio.GPIOS[this._gpioCol[c]].Low();
        for (var r = 0; r < this._gpioRow.Count; r++)
        {
            var pressed = _nusbio.GPIOS[this._gpioRow[r]].DigitalRead() == PinState.Low;
            if (pressed)
            {
                rr = new KeypadPressedInfo {
                    Row = r, Col = c, Key = this._keys[r][c]
                };
                break;
            }
        }
        _nusbio.GPIOS[this._gpioCol[c]].High();
        if (rr!=null)
            break;
    }
    return rr;
}

See on github the C# project. and the Keypad.cs class.

About the Wiring

One electricity rule that you may know is that if the + touch the - directly, you create a short circuit and it is not good. In between the + and - you must have a load, something that consume current. Therefore in between the 3 GPIO pins column and the 3 wires of the keypad I inserted 3 10 K Ohm resistor.






Saturday, November 5, 2016

How to make an LED fade in, fade out with 1 Nusbio GPIO

Overview

With one GPIO (General Purpose Input Output) from an Arduino, Raspberry PI or Nusbio you can easily turn one LED on or off.
But making the LED fade in and fade out is a little bit more complicated. With a micro-controller like an Arduino you can use a GPIO with PWM (Pulse with modulation) and call the method analogWrite(pin, value). The value defines what is called the duty cycle, in simple term this will be the intensity of the LED.



But with a Raspberry PI linked to Linux or Nusbio linked to Windows, there is no PWM (PWM is a hardware function, not available on PC and not managed by the OS).

So for this post I used an good old analog solution:

  • 1 transistor 2N3904
  • 1 100mF capacitor
  • 1 220k Ohm resistor
  • 1 1k Ohm resistor
Wired as follow:

This circuit looks simple, but it is not easy to understand how it works, though it does work as shown in the video.
And I will not try to explain it today.
If you are like me a software developer interested in learning analog electronic, it is a good example to start with because there are so many concepts involved to understand before you can picture how the all thing works:
  • LED voltage drop
  • Capacitor
  • Transistor
  • Sourcing and sinking current
 The first step is to try it on a bread board.

Use a red LED because the LED voltage drop makes a different, a blue LED would require different resistors.

Programming

The programming on the other side is simple, turn the LED on and wait for the LED to fade in,
then the LED off and wait for the LED to fade out.
The speed of the fade in fade out is controlled by the size of the capacitor and the resistance in between the GPIO and the base of the transistor (in my case a 220K Ohm).


var serialNumber = Nusbio.Detect();
if (serialNumber == null) // Detect the first Nusbio available
{
    Console.WriteLine("Nusbio not detected");
    return;
}
Console.Clear();
using (var nusbio = new Nusbio(serialNumber: serialNumber))
{
    ConsoleEx.WriteMenu(0, 1, "Q)uit");
    while (true)
    {
        Console.Write("On ");
        nusbio.GPIOS[0].High();
        Thread.Sleep(1000 * 3);
        Console.Write("Off ");
        nusbio.GPIOS[0].Low();
        Thread.Sleep(1000 * 3);
        if (Console.KeyAvailable && Console.ReadKey().Key == ConsoleKey.Q)
            break;
    }
}

Sunday, July 31, 2016

Nusbio SPI

Overview


The Serial Peripheral Interface (SPI) bus is a communication protocol primarily in embedded systems.
A lot devices like an EEPROM, SD card reader, graphic screen (AKA OLED) and more support the SPI protocol.
It is generally not available for Windows easily, though it is available on the Raspberry PI via Python and C.
That is why I created Nusbio.net that offers in a simple way to talk SPI from Windows and .NET.



For more information see the

C# Class

This post explains the SPIEngine .NET class for the Nusbio device.


Wiring

Since Nusbio has 8 gpio pins, you can setup an SPI bus and control up to 5 SPI devices. I generally use the following:
  • Gpio0 - CLOCK
  • Gpio1 - MOSI
  • Gpio2 - MISO
  • Gpio3 - CS 1
  • Gpio4 - CS 2
  • Gpio5 - CS 3
  • Gpio6 - CS 4
  • Gpio7 - CS 5

Controlling more than 5 SPI devices is for now not possible due to a software limitation in the class SPIEngine, which will be fixed by the end of 2017.

Note that you could use Gpio6 and Gpio7 to setup an I2C bus and therefore control for example
  • 3 SPI devices
  • 127 I2C devices
  • Using the SPI bus you could add an analog to digital converter (ADC) like the MCP3008 and therefore also add 8 ADCs (ADC TutorialSensors Extension).




Software

For each SPI device on the bus you must create an object of the class SPIEngine. After that you call the
the method Transfer() to send or receive data. You do not need to call the method Select() and Unselect() when calling Transfer().

public SPIEngine(Nusbio nusbio, 
                 NusbioGpio selectGpio, 
                 NusbioGpio mosiGpio, 
                 NusbioGpio misoGpio, 
                 NusbioGpio clockGpio, 
                 NusbioGpio resetGpio = NusbioGpio.None);

public SPIResult Transfer(byte b);

public SPIResult Transfer(List<byte> bytes, 
                          bool select = true, 
                          bool optimizeDataLine = false);


public SPIMode Mode;

public enum SPIMode
{
    MODE_CPOL0_CPHA0 = 0,
    MODE_CPOL1_CPHA0 = 1,
    MODE_CPOL0_CPHA1 = 2,
    MODE_CPOL1_CPHA1 = 3
}

public void Select()
public void Unselect()



Samples


I2C EEPROM


Here is a basic sample reading the first 4 pages of the SPI EEPROM 25AA1024 which is a 128 k bytes EEPROM with a page size of 256 bytes (20 mHz). We are therefore transferring 1 k bytes of data from the EEPROM to the PC.



var _eeprom = new EEPROM_25AA1024(
    nusbio   : nusbio,
    clockPin : NusbioGpio.Gpio0,
    mosiPin  : NusbioGpio.Gpio1, 
    misoPin  : NusbioGpio.Gpio2,
    selectPin: NusbioGpio.Gpio3
    );

var r = _eeprom.ReadPage(0, _eeprom.PAGE_SIZE * 4);
if(r.Succeeded)
{
    var data = r.Buffer;
}

// ...
// Class 25AA1024
// ...
public override EEPROM_BUFFER ReadPage(int addr, int len = -1)
{
    if (len == -1)
        len = PAGE_SIZE;

    var eb = new EEPROM_BUFFER();
    int byteSent = 0;
    var spiBufferWrite = GetEepromApiReadBuffer(addr);
    var spiBufferRead = GetEepromApiDataBuffer(len);
    var buffer = new List<byte>();
    buffer.AddRange(spiBufferWrite);
    buffer.AddRange(spiBufferRead);

    var r = this._spi.Transfer(buffer);
    if (r.Succeeded)
    {
        eb.Succeeded = true;
        eb.Buffer = r.ReadBuffer.GetRange(spiBufferWrite.Length, r.ReadBuffer.Count - spiBufferWrite.Length).ToArray();
    }
    return eb;
}



See full source code of class EEPROM_25AAXXX_BASE.cs.


Performance Improvement

By default the SPI transfer rate using Nusbio and a Windows machine is limited around 15 Kb/s.
There are 3 ways improve performance transfer giving from 20 Kb/s to 28 Kb/s depending of what type of SPI device your are controlling

  1. If there is no MISO (Master In Slave Out) needed or in other way if we only send data from the PC to the SPI device. In the constructor pass the miso parameter as None, and when calling the method Transfer() set the paramter optimizeDataLine to true. This will increase the output speed by about 33%.
  2. To force an SPI EEPROM to send the next 64 bytes of data from an EEPROM to the PC,  EEPROMs generally require that the master send 64 0 as byte. 64 0 is equal to 64 x 8 (512) bit set to 0. There is no need to set the data line to 0, 512 times, once is enough. Based on this concept the class EEPROM_25AAXXX_BASE.cs contains the method ReadPageOptimized(), which implement the optimization. It is open source and complicated. But this increase the performance from 15 k byte/s to 28 k byte/s.
  3. This third way only works for control APA 102 RGB LED and is kind a pushy. It consist to use the same cycle to set the data and to set the clock data line high. It gives a transfer rate up to 20 Kb/S.
    See the our Github C# project on Github Extension.APA102_2_StripAdapter.

 

OLED, Data Command Pin and SPI

Some SPI OLED  driver may requires an extra pin called DataOrCommand (D/C). This is not par per say part of the SPI protocol, but it is needed, to achieve better performance the SPIEngine class offers the following methods. The methods allow to package buffers of type Data and buffers of type Command and then send the buffers as SPI buffers with limited USB operations.

public void TransferNoMiso(bool reverse, List buffer);
public void TransferNoMiso(byte dataOrCommandBit, bool reverse, List PackagedBuffers);
public void TransferNoMiso(int dataOrCommand, byte dataOrCommandBit, bool reverse, List buffer);

See our folder Oled on Github for more information. We do support the SH1106 and SSD1306 OLED driver.




APA 102 RGB LED and SPI

The RGB LED (multi color LED) of type APA 102 use the SPI protocol and are supported by Nusbio.
See our Tutorial page.
See the our Github C# project on Github Extension.APA102_2_StripAdapter.



SPI Modes


The 4 spi modes have been implemented, but only the first mode has been tested.

  • MODE_CPOL0_CPHA0
  • MODE_CPOL1_CPHA0
  • MODE_CPOL0_CPHA1
  • MODE_CPOL1_CPHA1

Saturday, July 30, 2016

Nusbio I2C

Overview

The Inter-Integrated Circuit (I²C, i2c) is a multi-master, multi-slave serial communication protocol invented by Philips Semiconductor (now NXP Semiconductors), primarily used in embedded systems.
A lot devices like an EEPROM, LCD, GPIO expander, LED drivers and more support the I2c protocol.

It is generally not available for Windows easily, though it is available on the Raspberry PI via Python and C.

That is why I created Nusbio.net that offers in a simple way to talk I2C from Windows and .NET

A lot of devices designed by Adafruit use the I2C protocol and are compatibles with Nusbio and any .NET languages.

C# Class


This post explains the I2CEngine .NET class for the Nusbio device.

Wiring

Since Nusbio has 8 gpio pins, you can technically setup 4 independent I2C buses. But generally one is enough.
I use Gpio0 for SCL and Gpio1 for SDA as convention. Obviously you can connect multiple I2C devices to the bus.
Nusbio does not come with any pull up resistors so it is up you to take care of it.
Generally if you use an I2C breakout it is part of the breakout.

Software

For each I2C device on the bus you must create an object of the class I2CEngine. After that you call the WriteBuffer() method to initiate an I2C write operation and the method ReadBuffer for a I2C read operation.
The methods takes care of the I2C Control byte. You do not have to pass it as part of the buffer.
The methods return true if the operation succeeded. For the Readxxxx methods, if the operation succeeded you can then read the buffer which will be updated with the data.


public I2CEngine(Nusbio nusbio, NusbioGpio sdaOutPin, NusbioGpio sclPin, byte deviceId);
public bool ReadBuffer(int len, byte[] data);
public bool WriteBuffer(byte[] buffer);
public bool WriteBuffer(byte address8bit, byte[] buffer);


Samples


I2C EEPROM


Here is a basic sample reading the first 64 bytes of the I2C EEPROM 24LC256 which is a 32k bytes EEPROM with a page size of 64 byte.

byte EEPROM1_WR = 80; // 0xA0;
                                
var i2c = new I2CEngine(nusbio, NusbioGpio.Gpio1, NusbioGpio.Gpio0, EEPROM1_WR);
var addr = 0;
var buffer = new byte[64];
if (i2c.WriteBuffer(new byte[2] { (byte)(addr >> 8), (byte)(addr & 0xFF) }))
{
  var r = i2c.ReadBuffer(64, buffer);
}

We do offer specific classes to handle I2C and SPI EEPROM, see our folder EEPROM on github.


I2C MCP9808 Temperature Sensor

Here part of our class MCP9808 _Temperature Sensor.cs available on Github.
The method Begin will return true if the device is detected on the bus else false.

public bool Begin(byte deviceAddress = MCP9808_I2CADDR_DEFAULT)
{
    try
    {
        this._i2c.DeviceId = deviceAddress;
        if (read16(MCP9808_REG_MANUF_ID) != MCP9808_REG_MANUF_ID_ANSWER) return false;
        if (read16(MCP9808_REG_DEVICE_ID) != MCP9808_REG_DEVICE_ID_ANSWER) return false;
        return true;
    }
    catch (System.Exception ex)
    {
        System.Diagnostics.Trace.WriteLine(ex.ToString());
        return false;
    }
}

public double GetTemperature(TemperatureType type = TemperatureType.Celsius)
{
    uint16_t t = read16(MCP9808_REG_AMBIENT_TEMP);
    double temp = t & 0x0FFF;
    temp /= 16.0;
    if ((t & 0x1000) == 0x1000) temp -= 256;
    switch (type)
    {
        case TemperatureType.Celsius: return temp;
        case TemperatureType.Fahrenheit: return CelsiusToFahrenheit(temp);
        case TemperatureType.Kelvin: return temp*CELCIUS_TO_KELVIN;
        default:
            throw new ArgumentException();
    }
}

private UInt16 read16(uint8_t reg)
{
    UInt16 value = 0;

    if (this._i2c.WriteBuffer(new byte[1] { reg }))
    {
        var buffer = new byte[2];
        this._i2c.ReadBuffer(2, buffer);
        value = (System.UInt16)((buffer[0] << 8) + buffer[1]);
    }
    else throw new ArgumentException();    
}


We do offer specific classes to handle I2C and SPI EEPROM, see our folder EEPROM on github.


Advanced Methods

To improve transfer performance, the class I2CEngine expose the following methods which optimize the number of USB operations to execute the I2C operations (we combine an I2C Read + I2C Write operation in one USB transaction)

public bool Send16BitAddressAnd1Byte(int address16bit, byte b);
public bool Send16BitsAddressAndBuffer(int address16bit, int len, byte[] buffer);
public int  Send16BitsAddressAndRead1Byte(short address8bit);
public bool Send16BitsAddressAndReadBuffer(int address16bit, int len, byte[] data);

public bool Send1ByteCommand(byte command);
public bool Send2BytesCommand(byte command0, byte command1);
public bool Send3BytesCommand(byte command0, byte command1, byte command2);

public int Send1ByteRead1Byte(byte address8bits);
public _2BytesOrInt16Result Send1ByteRead2Bytes(byte cmd);        



Performance

Using the EEPROM 24LC256 which is an I2C 32k bytes with a max clock of 400 kHz, we can transfer the 32 k byte of data from the EEPROM to the PC at the rate of 15 k bytes per second in batch mode of 64 pages at a time.

Transferring one page a the time give a transfer rate of 8 k bytes per second.

Output or input batch mode is necessary to increase performance for all I2C devices.

Transfer speed may vary also depending on the speed of the computer.

 

Saturday, July 16, 2016

Faster serial port communication from .NET to Arduino

Overview

I was for a long time thinking that serial port communication on Windows and/or .NET was limited to 115 200 bauds, which translate to 11Kb/s at the most ( 115200 / 10 (8 bit-data + 2 (1-start-bit 1-stop-bit )) ).

In reality it is possible to use faster transfer rate, but there are a few things to know and it can be a little bit convoluted.

I am currently working on my "device" NusbioMCU, which use an Arduino Nano compatible (ATmega328),
so I will focus in this post on communication from Windows+.NET to different Arduino and compatibles.
But this can be applied to any serial communication from Windows and .NET.

This post should be taken with some grains of salt, because I am not an expert. I am just a guy that would like to do faster serial communication from Windows and .NET. This post is the fruit of my research and experimentation.


What do you need to know?

  • Hardware: You must know what UART chip is used in your MCU board. Different chip will support different baud rates, and the values may not be as expected.

    Popular UART chip:

    The Windows Device Manager program can help you figure this out. Below is the list of baud rate supported by the FT231X UART.

As shown in the image above, the FT231X UART which comes with the Adafruit Metro (a compatible Arduino UNO) support the 460 800 and  921 600 baud rates (Same for the FT232RL).


The Atmega16U2 UART which comes with a real Arduino UNO R3, will only display up to 128 000,
but multiplying this value by 2, 4 or 8 works.


Regarding the CH340, Chinese Arduino UNO or Nano compatibles comes with a CH340 UART which is limited to 115 200 bauds. That said based on information from RyanteckLTD and their device the RTK.Gpio, it could be possible that if the CH340 has its own 12 Mhz clock, it then can support faster transfer rates.

  • USB 2.0 Full Speed. The FTDI FT232RL or FT231X UART chips implement serial communication over USB 2.0 Full Speed. In USB 2.0 Full Speed there is a 1 ms latency to access the USB and transfer data. So if we transfer data in a 64 byte or less buffer, we cannot expect a transfer rate greater then 64 x 1000 == 53K b/s. 
    There are 2 transfer phases:
    1. From the PC to the UART at USB 2.0 Full Speed, dependent on the data buffer size
    2. From the UART to the MCU based on the baud rate. UART generally have an output buffer that allow to receive byte faster that they can sent according to the baud rate, but they are limted to 128 or 512 bytes
For example if we transfer data in buffer of 256 bytes at the USB level we can reach 212 Kb/s (256 * 1000 / 1024), that said since the max baud rate is 921 600 or 90 Kb/s I think the FTDI driver will stop the communication until the UART buffer is empty.
So for now I am only focusing on reaching 64 Kb/s.

  • Sofware:
    • The SerialPort class available in .NET does not support transfer speed greater than 115 200 bauds. The Windows low level API does support it, but the .NET implementation does not.
      See blog post If you *must* use .NET System.IO.Ports.SerialPort.
      Though is his blog post Ben Voigt gave some code small snippet that could work.
    • I did not find another open source and/or free library on the internet
    • With the Windows Serial Communication Component Library from Marshallsoft, I was able to achieve greater transfer speed.

 

Transfer Test

To test the transfer speed I am sending from the PC to the MCU 640 times, 4 buffers containing 33 bytes of data (82.5 Kb). Each buffer is processed by the MCU and the data is sent to a 32x8 LED matrix driven by 4 MAX7219 chips chained using the SPI protocol at 10Mhz (about 1 Mb/s).

There is no acknowledgment from MCU to the PC. I am visually testing the result for now, when there are issues the expected images is not display correctly on the matrix. When there is no issue I see a slight flickering of the expected images (see picture below).

The processing time by the MCU of one buffer takes less than 1 ms, and since there is a know 1 ms overhead when using USB 2.0 full speed, the PC is always working on sending the next buffer while the MCU is processing the current one. That said this will be an issue when the MCU take more than 1 ms to process the data. I did verified that the processing by the MCU does not affect the transfer in my case.

With that configuration I reached 33 Kb/s at 500 000 bauds. At  1 000 000 bauds no improvement.

Realizing that to get more transfer speed I needed to send more data I changed buffer size to 41 bytes of data (for total of 102.5 Kb) and reached 41Kb/s.

RTS/CTS
According to the schematic of the Arduino Uno R2 or Adafruit Arduino Metro, it looks like the RST/CTS pin are not wired to the MCU. So I guess there is no hardware control flow.

Summary

Here are my results using the Marshallsoft WSC library called from a C# program.

MCU UART Max Baud Rate Expected Kb/S Measured Kb/S
Arduino UNO R3 Atmega16U2 512 000 50 Kb/s 41 Kb/s
Adafruit Arduino Metro FT231X 500 000 48 Kb/s 41 Kb/s
Adafruit Trinket Pro + FTDI Cable FT232RL 500 000 48 Kb/s 41 Kb/s
Arduino Nano Compatible Chinese CH340 115 200 11 Kb/s 11 Kb/s

Note that the baud rates for the Atmega16U2 and FT231X are different, this is not a typo.

I do see a transfer speed increase from 115200 to 230400 and from 230400  to 460800.
But at 460800 or 500000 I do measure a transfer rate lower than expected.
And at 1 024 000 baud there is no improvement so far, with the FT231X, FT232RL and the Atmega16U2.

I think the issue here is that I need be able to send bigger buffer, but for that the Arduino need to be able to handle it, up to 41 Kb/s it is ok, after that it does not work (yet). The Arduino serial library only use a 64 bytes buffer and I think this is my problem. I would need to increase this buffer to 128 bytes and and send 64 bytes buffer to achieve 64 Kb/s. Well at least that is my expectation.


To-Do

  • Optimize processing and serial communication on the Arduino side to support buffer of 64 bytes
  • Test CH340 with its own 12 Mhz clock 
  • Test Cypress CP2130
To be continued.

Contact



To contact me see my web site MadeInTheUSB.net.










Friday, July 1, 2016

Controlling one 110 volts appliance safely with .NET (C#, VB.NET, F# or PowerShell)


Overview

Turning on and off an 110 volts appliance from a computer like a Raspberry PI/Python or a PC with an our device Nusbio.net using any .NET language, is not per say difficult.

You need one GPIO (General Purpose Input/Output) connected to what is called a Relay. A Relay looks like that.
The issue is that you must make the wiring yourself and this can be slightly dangerous. 

Solution

The company Digital-loggers introduced recently the IOTRelay. The IOTRealy takes care of every thing, it is safe, solid, easy to connect to and affordable $20.
  • On the side connect the cable to one of your outlet.
  • On the top you have 4 outlets
    • 2 are labelled normally ON, this is the one you will use to plug into your lamp,
      fan or toaster. Though we have 2 outlets, they are not independent.
    • 2 are labelled normally OFF, and turn the appliances when the IOTRelay is programmed to be off. I am not sure that this will be very useful.

 

Video

 

The wiring is simple:
  • Connect any of the 8 Nusbio's GPIO to the positive of the IOT Relay. 
  • Connect the negative of the IOT Relay to Nusbio's Ground.


Nusbio board + IOTRelay $36


Programming


From a software point of view all you have to do is turn the GPIO on or off to power your appliances.
Nusbio is compatible with C#, VB.NET, F# and PowerShell.

  nusbio[0].High(); // Turn appliance on
  nusbio[0].Low();  // Turn appliance off

Friday, May 27, 2016

Digital To Analog Converter For .NET, C# and VB.NET.

 Introduction

The world of Raspberry PI and Arduino offers
  • GPIO pins (General Purpose Input Output) 
  • ADC (Analog To Digital converter)
  • DAC (Digital To Analog Converter)
But what you may not know is that you can have these directly programmable to your Windows machine with any .NET languages using the USB device Nusbio.

DAC - Digital To Analog Converter

A DAC offers the ADC reverse function, that is to say starting with a integer range of values for example from 0 to 4097 (12 bits), output voltage between 0 and 5 volt, or 0 or 3.3 volt.

The MCP4725 is a 12 bit, 5 volts digital to analog converter that use the I2C protocol.
Adafruit offer a break out.



Here are 2 videos:


Analog To Digital Converter For .NET (C#, VB.NET, F#, PowerShell)

Introduction

The world of Raspberry PI and Arduino offers
  • GPIO pins (General Purpose Input Output) 
  • ADC (Analog To Digital converter)
  • DAC (Digital To Analog Converter)
But what you may not know is that you can have these directly programmable to your Windows machine with any .NET languages using the USB device Nusbio.

Videos

Analog Sensors

The analog extension offer 8 10 bits analog to digital converter similar as the one found on an Arduino UNO.
Any 5 or 3 volts analog sensor could be plugged into the extension and their values read from any .NET language.

Vibrator Sensor 


One TMP36 temperature sensor, one light sensor and one motion sensor plugged into the Analog Extension.
The source code to deal with the 3 sensors:

while (nusbio.Loop())
{
    if (halfSeconds.IsTimeOut())
    {
        const int lightSensorAnalogPort = 6;
        const int motionSensorAnalogPort = 2;
        const int temperatureSensorAnalogPort = 0;

        ConsoleEx.WriteLine(0, 2, string.Format("{0,-20}", DateTime.Now, lightSensor.AnalogValue), ConsoleColor.Cyan);

        lightSensor.SetAnalogValue(ad.Read(lightSensorAnalogPort));
        ConsoleEx.WriteLine(0, 4, string.Format("Light Sensor       : {0} (ADValue:{1:000.000}, Volt:{2:000.000})    ",
            lightSensor.CalibratedValue.PadRight(18),
            lightSensor.AnalogValue,
            lightSensor.Voltage), ConsoleColor.Cyan);

        analogTempSensor.SetAnalogValue(ad.Read(temperatureSensorAnalogPort));
        ConsoleEx.WriteLine(0, 6, string.Format("Temperature Sensor : {0:00.00}C, {1:00.00}F     (ADValue:{2:0000}, Volt:{3:000.000})      ",
            analogTempSensor.GetTemperature(AnalogTemperatureSensor.TemperatureType.Celsius),
            analogTempSensor.GetTemperature(AnalogTemperatureSensor.TemperatureType.Fahrenheit),
            analogTempSensor.AnalogValue,
            analogTempSensor.Voltage), ConsoleColor.Cyan);

        analogMotionSensor.SetAnalogValue(ad.Read(motionSensorAnalogPort));
        var motionType = analogMotionSensor.MotionDetected();
        if (motionType == DigitalMotionSensorPIR.MotionDetectedType.MotionDetected || motionType == DigitalMotionSensorPIR.MotionDetectedType.None)
        {
            ConsoleEx.Write(0, 8, string.Format("Motion Sensor     : {0,-20} (ADValue:{1:000.000}, Volt:{2:000.000})", motionType, analogMotionSensor.AnalogValue, analogMotionSensor.Voltage), ConsoleColor.Cyan);
        }
    }
} 

This touch sensor only require a digital GPIO, when you finger touch the panel the value at the gpio is a 1.
It could also be plugged into the analog extension.

DAC - Digital To Analog Converter

A DAC offers the ADC reverse function, that is to say starting with a integer range of values for example from 0 to 4097 (12 bits), output voltage between 0 and 5 volt, or 0 or 3.3 volt.

The MCP4725 is a 12 bit, 5 volts digital to analog converter that use the I2C protocol.
Adafruit offer a break out.



Here are 2 videos:


Sunday, May 22, 2016

Controller Extension Tutorial - Part II

Overview

You can read part I at of this post at Controller Extension Tutorial - Part I.

Beyond 5 volt

Some devices will require 8 or 12 volt, therefore we offer a second extension which allow to plug an external source of power like a 9 volt battery.
Both extension use the transistor 2N3904 which support 12 volt, but the current is still limited to 200 mA per external device controlled.

Beyond the USB 500 milliamp


Note that if each device controlled are 5 volts but require 200 mA each, we cannot use the USB to provide the 600 mA. USB 2.0 only allow to consume 500 mA. In this case we need a 5 volt power adapter providing 600 mA or more.


The extension is configured to use an external source of power by default. But we can revert it back to use the USB power, by de-soldering the connection EX_PWR_ON and solder the connection USB_PWR_ON.

Connecting all the pieces

Now, we have 4 items
  1. The Nusbio board
  2. The Controller Extension
  3. The 9 volts lamp
  4. An external source of power, here a 9 volt battery

Plug the extension into Nusbio and
  • The black wire from the device must be plugged into the G0 pin (Ground 0)
  • The red wire from the device must be plugged into the V0 pin (VCC 0, in short VCC mean +)
  • The black wire or negative from the battery into the EX_POWER_PIN negative pin
  • The red wire or positive from the battery into the EX_POWER_PIN positive pin



Programming

The change of voltage  from 5 to 9 volt does not affect the programming.
The shortest code would look like this and will turn on the device for 500 ms and turn it off for another 500 ms.

var serialNumber = Nusbio.Detect();
if (serialNumber == null) // Detect the first Nusbio available
{
    Console.WriteLine("Nusbio not detected"); return;
}
using (var nusbio = new Nusbio(serialNumber)
{
    while(true) {
        nusbio.GPIOS[NusbioGpio.Gpio0].DigitalWrite(true);
        Thread.Sleep(500);
        nusbio.GPIOS[NusbioGpio.Gpio0].DigitalWrite(false);
        Thread.Sleep(500);
    }
}

To learn more

  Transistor Crash Course For Software Developer - PART I - Transistor As Switch  
  Measuring Current with a Digital Multimeter
  YouTube is your friend, if you want to learn electricity

Saturday, May 21, 2016

Controller Extension Tutorial - Part I

Overview


The Nusbio's Controller Extension allows to turn on and off programmatically using any .NET language up to 3 devices.


In this part I, I will use the simple version of the extension which automatically provide current to power the devices and therefore each device must be 5 volts.
The limit of current per device is 200 milli-amp (mA) because this is the limit of the 2N3904 transistor used by the extension.
Also the total consumption must be less than 500 milli-amp, because this is the USB limit and the devices are really powered by the USB of the computer.

The rule of thumb is that an LED use 20 mA and this lamp has 3 so 60 mA. Simple motor found in printer will use 100 mA. To learn how to measure current consumption, see links at the end of this post.


Where to start?

Pick a 5 volts device like this lamp, even if the device is powered with battery like 3 AA battery (3 x 1.5 ~= 4.5 ~= 5 Volts ) and attach or solder a black wire to the negative and a red wire to the positive. Just follow the current black and red wire currently hooked from the batteries to the device.



a


Now, we have 3 items
  1. The Nusbio board
  2. The Controller Extension
  3. The 5 volts lamp



Plug the extension into Nusbio and
  • The black wire from the device must be plugged into the G0 pin (Ground 0)
  • The red wire from the device must be plugged into the V0 pin (VCC 0, in short VCC mean +)
  • Turning on or off Nusbio GPIO 0 programmatically will power or not the device



Programming

The shortest code would look like this and will turn on the device for 500 ms and turn it off for another 500 ms. The Nusbio .NET library is written in C# compiled as .NET 4.0 and therefore compatible with VB.NET, F#, PowerShell and IronPython.

var serialNumber = Nusbio.Detect();
if (serialNumber == null) // Detect the first Nusbio available
{
    Console.WriteLine("Nusbio not detected"); return;
}
using (var nusbio = new Nusbio(serialNumber)
{
    while(true) {
        nusbio.GPIOS[NusbioGpio.Gpio0].DigitalWrite(true);
        Thread.Sleep(500);
        nusbio.GPIOS[NusbioGpio.Gpio0].DigitalWrite(false);
        Thread.Sleep(500);
    }
}
 

To learn more

  Transistor Crash Course For Software Developer - PART I - Transistor As Switch  
  Measuring Current with a Digital Multimeter
  YouTube is your friend, if you want to learn electricity

Saturday, April 16, 2016

Transistor Crash Course For Software Developer - PART I - Transistor As Switch

Overview


If you are a software developer that started making hardware experiment with an Arduino, Raspberry PI, BeagleBone or our USB device Nusbio, You probably learn by now about GPIO (General Purpose Input Ouput).
These pins with which we can programmatically send a 1 or 0 or read a 1 or 0 when connected to another device.
A 1 also called high (pulling the wire high) is materialized by sending
some voltage/current (3 or 5 volts generally) and a 0 also called a low materialized by sending no voltage/current.

Though we can turn on and off device with a GPIO, a GPIO generally can only provide a limited amount of current. An Arduino Uno GPIO can provide up to 40 mA of current (ArduinoPinCurrentLimitations).
Nusbio's GPIO are configured by default to provide 4 mA and can be configured to provide up to 16 mA.

Therefore when you want to control a device like a simple motor or an LED using 60 mA, you should not connect the GPIO directly to the positive of the device. It may work, but the motor may go very slow or the LED will not be very bright.

If the device is 5 or 12 volts, you can use a transistor. If the device is 110 volts, you need a relay.



Transistors 


Disclaimer: This is a very quick introduction to transistor to be used as switch. My goal is to get you enough information so you can turn on and off devices that require between 40 and 400 mA of current with Nusbio's GPIOS.

Usage

Transistor can be used as
  • Switch
  • Amplifier
  • Binary logic

Type

There are multiples types of transistor, if you just need to remember 2 types
  1. BJT (Bipolar junction transistor)
    • Activated by sending some current to the base (more on this later) 
    • NPN, default off, activated when current is sent to base
    • PNP, default on, de-activated when current is sent to base
  2. MOSFET (metal–oxide–semiconductor field-effect transistor)
    • Activated by sending some voltage at the gate (more on MOSFET)
    • N-Chanel, default off, activated when voltage is sent to base
    • P-Chanel default on, de-activated when voltage is sent to base

Switch Configuration

In this paragraph we are going to use a BJT transistor and configure it as a Switch. A BJT transistor has 3 pins C, B , E.

  • The C stand for Collector. Remember the following:
        In a Switch mode configuration the Collector collect the load.
    What that mean is in a electrical circuit one component is consuming current (a light or motor), that is the load. The transistor Collector should be plugged just after the component creating the load.
    The negative of the controlled device should be connected the collector and the positive of the controlled device should connected to the source of power. As a software developer I would call it the input.
  • E stands for Emitter which in a Switch mode should be connected to ground, as a software developer I would call it the output.
  • B stands for base which is connected to for example a GPIO, as a software developer I would call it the API. Don't forget to add in between the GPIO and the base a resistor (for now let's say 1k).
In short the current will flow from C to E, if a small amount of current is sent to B (for NPN transistor)

Datasheet

Double check the transistor datasheet to know the maximum voltage and current supported by the transistor.

I often use the 2N3904,  it is a BJT NPN. In datasheet I found the following

The maximum voltage supported is 40 (Vceo) and the maximum current that can flow throw the transistor is 200 mA (Ic). Nusbio power comes from the USB and is 5 volts.

Eat Big Cookie

How do I find which pin is which? Turn the flat face toward you and say out load Eat Big Cookie.



Nusbio + Transistor


Wiring a BJT to Nusbio on a breadboard should look like that (it would be the same with an Arduino or Raspberry PI)



Videos

A video from MAKE and Collin Cunningham: MAKE presents: The Transistor

Sunday, February 21, 2016

Configuring Nusbio GPIO to drive up to 16 mA of current

Overview

All Nusbio's 8 GPIOs are configured to source/sink 4 mA of current.

If you need the 8 gpios to source or sink 16 mA of current if possible to activate this mode using the Nusbio Console application.

We noticed that in 16mA of current mode I2C bus does not work.
  1. Execute the console
  2. Select the C)onfiguration option
  3. Verify that the setting ADDriveCurrent is set to 4 
  4. Hit the enter key
  5. Answer Y)es at the question: Increase GPIO current drive/sink to 16 mA Y)es N)o
  6. Once the operation is done, unplug Nusbio, wait 5 seconds and plug back Nusbio








Monday, February 15, 2016

FT232 versus FT231

Overview


In his Adafruit interview Fred Dart, the CEO of FTDI, talked about the differences between the UART FT232 and FT231.

For the design of the Nusbio, I started with the FT232R and later switched to the FT231X.
I spent a good amount of time studying the 2 chips.



I was surprise to hear that:
"it can only drive out at 3.3V max though it has 5V tolerant inputs"
and also in the interview it was not mentioned that the FT231X has a 1024 bytes (512+512) transfer buffer, versus the FT232 which only has a 384 bytes transfer buffer (128 + 256). The buffer size in synchronous bit banging mode makes a big difference in terms of byte/second transferred.




The FT231X has multiple advantages over the FT232R
  1. Price
    $2.12 over $4.50 for one chip.
  2. Buffer size 1024 over 384. A larger buffer increase the transfer performance when using the synchronous or asynchronous bit banging mode. I do not know if this make a difference in UART mode (I supposed it should) but with Windows the serial port are limited 128 000 bauds.
  3. Package
    SSOP-20 over SSOP-28, easier to solder. For both I would not use a regular solder iron. I recommend to use an "electric skillet"or toaster. Obviously the FT231X take less space on the board.
  4. Voltage
    Based on the FT231X datasheet the 3.3 Volt out should feed VCCIO, therefore all 8 GPIO would output 3.3V. Making it a 3.3V devices.
    For now in Nusbio I feed VCCIO with the USB 5V or 3.3V configurable with a jumper or a soldered connector. By default it is set to 5V, making Nusbio a 5V device.

    I need to check with FTDI if that is ok, though it seems to work and Fred Dart confirmed the input are 5V tolerant. The question is the output and VCCIO are 5V tolerant.

    At the URL http://www.ftdichip.com/Products/ICs/FT231X.html, I found this
          True 3.3V CMOS drive output and TTL input.
          (operates down to 1V8 with external pull ups and is also 5V tolerant)
    From Twitter @FTDICHIP sent me back the following:
    the VCCIO is really meant to be 3.3V Absolute max ratings as quoted are this. It will withstand a 5V input but output at 3.3V.

    I am going to update Nusbio board to send 3.3V to VCCIO, this mean the 8 GPIOs will send 3.3V.  Nusbio VCC will remains 5V with up to 500 mA.

  5. Clock
    With the FT232R, there is an issue with the internal clock in bit banging mode. It can only be viewed with an Oscilloscope. The clock is not stable. If you bit bang 1 0 1 0 1 0, you would expect a stable 50% duty cycle what ever the baud rate. But what I saw on the Oscilloscope was all over the place. I found one person on the FTDI forum that remarked the same problem. Adding an external clock fixed the problem (Adding an external clock does not increase performance).
The FT231X has multiple disadvantages over the FT232R.
  1. The USB data lines require each a 27Ohm resistor and a 47pF capacitor.
    More work to build a device
  2. FT232R is definitely 5 or 3.3 volts chip, where the FT231X is a 3.3V chip (though the gpio input are 5V tolerant. And gpio can be configured to 5V, but not "recommended" by FTDI)