Notes About Working with Various Arduino & Netduino Microcontroller Boards

Thursday, May 30, 2013

Arduino C Code to Convert a Float to a String

Here is a snippet of code that demonstrates using the dtostrf()function of the avr-gcc stdlib to convert a float value to a string (array of chars).

A call to dtostrf takes four arguments:

  1. A floating point value to be converted
  2. An integer indicating the minimum width (number of characters) for the output - including the decimal point and any leading minus sign.  The output will be padded on the left side with spaces if the overall output is shorter than this value.
  3. An integer to specify the number of digits to the right of the decimal place. The output will be padded with zeros on the right, if necessary. 
  4. An array of chars to hold the converted value.  Be sure the array has enough room for all characters in  output.

Be sure to include stdlib.h.

Here is the portion of Arduino C:

#include <stdlib.h>
.
.
.

float h = dht.readHumidity();
float t = dht.readTemperature() * 9/5 + 32;
char tempF[6]; // buffer for temp incl. decimal point & possible minus sign
char rhPct[6]; // buffer for humidity incl. decimal point
dtostrf(t, 6, 2, tempF); // Min. 6 chars wide incl. decimal point, 2 digits right of decimal
mySerial.write(tempF);
mySerial.write("F ");
dtostrf(h, 6, 2, rhPct);
mySerial.write(rhPct);
mySerial.write("%");
mySerial.write("\r\n");
.
.
.


Note (June 13, 2013):

/* As of early June 2013, dtostrf is not implemented in the Arduino IDE 1.5 libraries -
   but it will be implemented in the future. Use this function in the meantime
   See http://forum.arduino.cc/index.php?topic=170564.0. */
char *dtostrf (double val, signed char width, unsigned char prec, char *sout) {
  char fmt[20];
  sprintf(fmt, "%%%d.%df", width, prec);
  sprintf(sout, fmt, val);
  return sout;

}

Friday, May 24, 2013

Example Serial Communication between an Arduino & a Beaglebone Black (Arduino Side)


Here is an example of serial communication between an Arduino Uno and a Beaglebone Black. This example has an Adafruit NFC/RFID Shield attached to the Arduino (as part of a larger application).  The RFID shield reads an RFID tag and sends the tag's ID number to the Beaglebone Black over a serial connection using a very simple protocol. The Beaglebone Black then responds over the same connection. Eventually, I will have the Beaglebone check the tag ID against a database and record the usage of the tag, but this example does not go that far. This isn't meant to be a complete RFID or authentication example - the serial connection itself is more relevant here.

The Beaglebone Black portion of this post is here.

Connections


This example uses a Sparkfun logic level converter to bridge the voltage gap between the Arduino Uno (5V) and the Beaglebone Black (3V3).

Arduino/NFC Logic Level Conv.  Beaglebone Black
5V          HV HV
GND         HV GND
Digital 5   HV TXO / LV TXI    P9 24 (UART1_TXD)
Digital 6   HV RXI / LV RXO    P9 26 (UART1_RXD)
                            LV LV              P9 3  (3V3)
            LV GND             P9 1  (GND)


Code


You will need the Adafruit_NFCShield_I2C library to get this example to work.  This example prints output to the serial console and uses the SoftSerial library for the communication between the Arduino and the Beaglebone. 

#include <Wire.h>
#include <Adafruit_NFCShield_I2C.h>
#include <SoftwareSerial.h>

#define IRQ   (2)  // Shield's IRQ line uses D2
#define RESET (3)  // Not connected on NFC Shield
#define RX (5)     // Can use other available pins 
#define TX (6)     // for SoftSerial RX/TX

String resp = "";

Adafruit_NFCShield_I2C nfc(IRQ, RESET);

SoftwareSerial mySerial(RX, TX);

void setup(void) {
  Serial.begin(38400);
  nfc.begin();
  nfc.SAMConfig();
  
  mySerial.begin(38400);
}

void loop(void) {
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer for returned UID
  uint8_t uidLength;         

  // Check for response from Beaglebone 
  while(mySerial.available()>0) {
    char c = mySerial.read();
    resp += c;
    if(c == '\n') {
      Serial.print(resp);
      resp = "";
    }
  }
  
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
  if (success) {
     mySerial.print('^');  // Marks start of data packet
     for(int c = 0; c < uidLength; c++) {
       mySerial.print(uid[c], HEX);
     }
     mySerial.print("\r\n"); // Marks end of data packet
     mySerial.flush();
  }
  delay(500); 
}

Thursday, May 16, 2013

TCS34725 RGB Color Sensor & the Netduino Plus 2

The TCS34725 RGB color sensor board from Adafruit works with the Netduino Plus 2 using an I2C connection. You can find the datasheet here. The C# example below reports the clear, red, green, and blue light levels for a given sample (printing them to the debug console in Visual Studio).

Connections


Connect SDA, SCL, 3V3, and GND on the sensor to the corresponding pins on the Netduino Plus 2.  No pull-up resistors are needed (they are included in the breakout board).


Code


using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace TCS34725
{
    public class Program
    {
        const int DEV_ADDR   = 0x29;
        const int CMD_BIT    = 0x80;
        const int ENABLE     = 0x00;
        const int ENABLE_PON = 0x01;
        const int ENABLE_AEN = 0x02;
        const int DEV_ID     = 0x12;
        const int RGB_DATA   = 0x14;
  
        public static void Main()
        {
            I2CDevice tcs = new I2CDevice(
                new I2CDevice.Configuration(DEV_ADDR, 100)
            );

            byte[] getIDCmd = { CMD_BIT | DEV_ID };
            byte[] id = { 0 };
            I2CDevice.I2CTransaction[] getDevID = new I2CDevice.I2CTransaction[] {
                I2CDevice.CreateWriteTransaction(getIDCmd),
                I2CDevice.CreateReadTransaction(id)
            };
            int bytesRead = tcs.Execute(getDevID, 100);
            if (id[0] == 0x44)
            {
                Debug.Print("\nOK - Device found.\n");
            }
            else
            {
                Debug.Print("\nERROR - Device not found.\n");
                while(true) { ; }
            }

            byte[] beginCmd = { CMD_BIT | ENABLE, (ENABLE_PON | ENABLE_AEN) & 0xFF };
            I2CDevice.I2CTransaction[] begin = new I2CDevice.I2CTransaction[] {
                I2CDevice.CreateWriteTransaction(beginCmd)
            };
            bytesRead = tcs.Execute(begin, 100);

            while (true)
            {
                byte[] readCmd = { CMD_BIT | RGB_DATA };
                byte[] colorData = { 0, 0, 0, 0, 0, 0, 0, 0 };
                I2CDevice.I2CTransaction[] read = new I2CDevice.I2CTransaction[] {
                    I2CDevice.CreateWriteTransaction(readCmd),
                    I2CDevice.CreateReadTransaction(colorData)
                };
                bytesRead = tcs.Execute(read, 100);
                int clear = ((colorData[1] << 8) | colorData[0]);
                int red = ((colorData[3] << 8) | colorData[2]);
                int green = ((colorData[5] << 8) | colorData[4]);
                int blue = ((colorData[7] << 8) | colorData[6]);
                string result = "C: " + clear.ToString() + " ";
                result += "R: " + red.ToString() + " ";
                result += "G: " + green.ToString() + " ";
                result += "B: " + blue.ToString();
                Debug.Print(result);
                Thread.Sleep(1000);
            }
        } 
    }
}