Notes About Working with Various Arduino & Netduino Microcontroller Boards

Saturday, June 23, 2012

Using Chronodot Square Wave to Count Seconds


I was a bit dense when I first tried to use the Chronodot v2.1 real-time clock's square wave function to count seconds. I finally came up with some very simple code that got me started. There are more complex examples out there, but I couldn't see the forest for the trees when trying to make sense of them. The sample below just counts the seconds and prints them to the serial monitor.

For some reason, I can't get this to work on the Arduino Leonardo (even with connection to SDA and SCL pins on Leonardo).
Connections between the Chronodot and  the Arduino Uno are:
SCL --> A5
SDA --> A4
SQW --> D2
VCC --> 5V
GND --> GND

Here's the sketch:

#include <Wire.h>

#define intPin   2
#define intNum   0
#define ds3231   0x68
#define ctrlReg  0x0E
// bits 4 & 3 in ctrlByte set to 0 = 1Hz
#define ctrlByte 0b00000000 

volatile unsigned int c = 0;

void setup()
{
  pinMode(intPin, INPUT);
  //Use built-in pull-up resistor on D2
  digitalWrite(intPin, HIGH);
  attachInterrupt(intNum, handleInterrupt, FALLING);
  Wire.begin();
  Serial.begin(115200);
  Wire.beginTransmission(ds3231); 
  Wire.write(ctrlReg); 
  Wire.write(ctrlByte);
  Wire.endTransmission();
}

void handleInterrupt() {
  Serial.println(++c);
}

void loop() { ; }

Monday, June 18, 2012

Links for Parallax RFID R/W

The following links cover the Parallax RFID read-write unit (model 28440, black rather than blue color of the read-only RFID unit).

Data Sheet
Sample Code (Arduino Playground)

Note that the code - as given - has different addresses in the samples for reading and writing, so the results may not work as expected without modifying the address that is written or read.

The write-data example sets the location to 4 in this line:

#define whichSpace 4

The read-data example, however, has this code that causes it to read from location 32:

void loop()
{
 int val;
  mySerial.print("!RW");
  mySerial.write(byte(RFID_READ));
  mySerial.write(byte(32));

To read back from location 4 (used in the write code), use this:

void loop()
{
 int val;
  mySerial.print("!RW");
  mySerial.write(byte(RFID_READ));
  mySerial.write(byte(4));

Sunday, June 17, 2012

Arduino Leonardo & RS232 Shield

The RS232 shield for Arduino that I got from CuteDigi covers the new stand-alone SDA and SCL pins on the Arduino Leonardo. 

To work around this problem, I attached a couple preformed jumper wires to these pins on the Leonardo. These preformed wires are low enough in profile that the RS232 shield still seats completely.  The section of the shield board above these pins is blank, so there is no danger of a short circuit.

After some further research, I have also found that pins D2 and D3 on the Leonardo correspond to SDA and SCL. So, there are a couple ways to avoid the problem of the obstructed SDA and SCL pins when using the RS232 Arduino shield on the Leonardo.


Sunday, June 10, 2012

C# Code for Using Parallax RFID Reader with Netduino

The following event-driven code for using the Parallax RFID reader is taken from posts in the Netduino Community Forum. The code is only slightly modified from the the code posted there by afulki.

Be sure to add the reference to Microsoft.SPOT.Hardware.SerialPort.dll.


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

/* Change next line to end in Netduino or NetduionoPlus
 * as appropriate */
using SecretLabs.NETMF.Hardware.NetduinoPlus;

using System.IO.Ports;

public class RFID
{
    private int readDelay = 1500;
    private bool readerEnabled = false;

    public SerialPort Serial { get; set; }
    public OutputPort RfidCtrl { get; set; }

    public delegate void CardReadEventHandler(RFID sender, string cardID);
    public event CardReadEventHandler OnCardRead;

    public delegate void StatusChangedEventHandler(RFID sender, bool readerEnabled);
    public event StatusChangedEventHandler OnStatusChanged;

    private byte[] msgBuffer = new byte[10];

    // -1 = waiting for start char, 0 or more means reading message
    private int msgCounter = -1; 

    public int ReadDelay
    {
        get { return readDelay; }
        set { readDelay = value; }
    }

    public bool ReaderEnabled
    {
        get { return readerEnabled; }
        private set
        {
            readerEnabled = value;
            if (OnStatusChanged != null)
            {
                OnStatusChanged(this, value);
            }
        }
    }

    public RFID(string port, Cpu.Pin ctrlPin, bool autoEnable = true)
        : this(new SerialPort(port, 2400, Parity.None, 8, StopBits.One), new OutputPort(ctrlPin, false), autoEnable)
    {
    }

    public RFID(SerialPort sPort, OutputPort rfidCtrl, bool autoEnable = true)
    {
        this.Serial = sPort;
        this.RfidCtrl = rfidCtrl;

        Serial.WriteTimeout = 1000;

        Serial.Open();
        Serial.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);

        if (autoEnable) EnableReader();
    }

    public void DisableReader()
    {
        RfidCtrl.Write(true);
        if (Serial.IsOpen) Serial.Close();
        ReaderEnabled = false;
    }

    public void EnableReader()
    {
        if (!Serial.IsOpen) Serial.Open();
        RfidCtrl.Write(false);
        ReaderEnabled = true;
    }

    private void DoReadDelay()
    {
        if (ReaderEnabled)
        {
            DisableReader();
            Thread.Sleep(ReadDelay);
            EnableReader();
        }
    }


    void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;

        while (sp.BytesToRead > 0)
        {
            // temp buff to hold message,
            byte[] buf = new byte[1];

            // Read a single byte from the recv buffer,
            if (sp.Read(buf, 0, 1) > 0)
            {
                // Start of Message?
                if (buf[0] == '\n')
                {
                    msgCounter = 0;
                }
                // End of message?
                else if (buf[0] == '\r')
                {
                    if (msgCounter > 9)
                    {
                        String cardID = String.Empty;
                        for (int i = 0; i < 10; i++)
                        {
                            cardID += (char)msgBuffer[i];
                        }

                        if (OnCardRead != null)
                        {
                            OnCardRead(this, cardID);
                        }
                    }

                    msgCounter = -1;
                    DoReadDelay();
                }
                else // Store it in the global buffer, 
                {
                    if (msgCounter < 10)
                    {
                        msgBuffer[msgCounter++] = buf[0];
                    }
                    else
                        msgCounter = -1;
                }
            }
        }
    }

    // Added Main for quick test of code 
    public static void Main()
    {
        // /Enable connected to pin D2
        RFID rfid = new RFID(SerialPorts.COM1, Pins.GPIO_PIN_D2);
        rfid.OnCardRead += new RFID.CardReadEventHandler(rfid_OnCardRead);

        Thread.Sleep(Timeout.Infinite);
    }

    static void rfid_OnCardRead(RFID sender, string cardID)
    {
        Debug.Print("CardID: " + cardID);
    }
}

Saturday, June 9, 2012

Arduino Leonardo: Serial versus Serial1

Today I received the Parallax RFID reader that I had ordered. I decided to give it a quick test with my Arduino Leonardo. I took the sample code from the Arduino Playground (Code for Using the Arduino with the Parallax RFID Reader), but found that it didn't work. The code works fine on my Arduino Uno, but not on the Leonardo. 

The Arduino Serial Reference page held the key: Serial is for accessing the USB connection between the Leonardo and the IDE serial monitor. For serial communications via digital pins 0 and 1, use Serial1

I had read that the Leonardo had separated USB and serial communications, but I hadn't translated that into real-world practice. Obviously, this issue will come up with any code using serial communication with anything other than the serial monitor in the IDE.

While on the subject of serial ports and the Leonardo, I note that the connection between the IDE and the Leonardo was not very stable when I used one of the USB ports on my monitor. I kept getting memory buffer errors when trying to upload sketches and the Serial Port option on the Tools menu stopped showing the serial port that I had previously chosen. Using a USB port on the computer itself resolved this issue.


I am starting this blog as a place to assemble notes and links to resources relevant to my getting to know the Arduino and Netduino. I am in the early stages of my venture into the Internet of things, so the material here may most useful to myself, but if it is useful to others, so much the better.