Arduinio Serial

I’m trying to do a simple serial connection between an Arduino Mega board and the elecric imp. The Arduino is sending a string that I am trying to post to either the log or the planner. The Imp seems to be dropping many of the bytes in the string, even at lower baud rates. My imp and arduino code is based of the Sparkfun Serial connection example. Is there a better way to read in a string? I eventually want to be able to log the data to a google docs spreadsheet ideally.

Take not, I’m a fairly rank beginner, so I’m sure I’m making fairly basic mistakes.

//Transmit Serial Data from Arduino

// impeeIn will override the InputPort class.
// Whenever data is received to the impee, we’ll jump into the set© function defined within

class impeeIn extends InputPort
{
name = “UART Out”;
type = “string”;

// This function takes whatever character was sent to the impee
// and sends it out over the UART5/7. We'll also toggle the txLed
function set(c)
{
    //hardware.uart57.write(c);
}

}

local impeeInput = impeeIn(); // assign impeeIn class to the impeeInput
local impeeOutput = OutputPort(“UART In”, “string”); // set impeeOutput as a string

function initUart()
{
hardware.configure(UART_57); // Using UART on pins 5 and 7
hardware.uart57.configure(2400, 8, PARITY_NONE, 1, NO_CTSRTS); // 19200 baud worked well, no parity, 1 stop bit, 8 data bits
}

// This is our UART polling function. We’ll call it once at the beginning of the program,
// then it calls itself every 10us. If there is data in the UART57 buffer, this will read
// as much of it as it can, and send it out of the impee’s outputPort.
function pollUart()
{
imp.wakeup(0.0001, pollUart.bindenv(this)); // schedule the next poll in 10us

local byte = hardware.uart57.read();    // read the UART buffer
// This will return -1 if there is no data to be read.
while (byte != -1)  // otherwise, we keep reading until there is no data to be read.
{
    server.log(format("%c", byte)); // send the character out to the server log. Optional, great for debugging
    server.show(byte);
    impeeOutput.set(byte);  // send the valid character out the impee's outputPort
    byte = hardware.uart57.read();  // read from the UART buffer again (not sure if it's a valid character yet)

}

// This is where our program actually starts! Previous stuff was all function and variable declaration.
// This’ll configure our impee. It’s name is “ArduinoSerial”, and it has both an input and output to be connected:

imp.configure(“ArduinoSerial”, [], [impeeOutput]);

initUart(); // Initialize the UART, called just once
pollUart(); // start the UART polling, this function continues to call itself
// From here, two main functions are at play:
// 1. We’ll be calling pollUart every 10us. If data is sent from the UART, we’ll send out out of the impee.
// 2. If data is sent into the impee, we’ll jump into the set function in the InputPort.
//
// The end

To me this looks like your wakeup time is far too short. The uart class has a receive buffer (of an undisclosed size) so you don’t have to poll as fast as you do. Perhaps using a time of 100ms might work better.

As an aside it would be nice to have a uart class with flow control. And knowing what size the buffer is so we could pick an appropriate poll time.

Buffer is currently 80 bytes in each direction. It’ll eventually be settable in the configure call.

One issue is probably the server.log, server.show and server.set. Each of these is a separate packet to the server, and the set will force the TCP stack to flush and send accumulated packets.

You really ought to be building a string of the received characters, THEN sending them all at once when the buffer has been emptied, eg:

// Collect bytes
local s = “”;
local byte = hardware.uart57.read();
while(byte != -1) {
s+=byte.tochar();
byte = hardware.uart57.read();
}

// If we got anything, send it all as a string
if (s.len()) impeeOutput.set(s);

…one of the next things on the list is being able to register a handler for serial input so you don’t need to poll.

That worked much better. Thanks for the help!

I am attempting similar, trying to pass multiple sensor values from the Arduino to IMP via the serial port. I have it working, passing a string with various sensor values, now am looking at how to parse that string into separate values so the Arduino can do things with it, like post to CMOS datastreams.

I was first thinking of leveraging the http JSON parser, but now I see that is server side only. I’ve looked at various squirrel docs, but can not see examples on how to parse a string.

Any hints or suggestions?

split() is useful here, eg:

local string=“1 2 3 4.5 6 7”;
local sp = split(string, " ");
foreach(n,a in sp) {
server.log("reading “+n+” = "+a);
}

…gives this output:

Wed, 06 Mar 2013 04:38:58 GMT: reading 0 = 1
Wed, 06 Mar 2013 04:38:58 GMT: reading 1 = 2
Wed, 06 Mar 2013 04:38:58 GMT: reading 2 = 3
Wed, 06 Mar 2013 04:38:58 GMT: reading 3 = 4.5
Wed, 06 Mar 2013 04:38:58 GMT: reading 4 = 6
Wed, 06 Mar 2013 04:38:58 GMT: reading 5 = 7

One approach is to read the bytes one at a time and take action depending on what comes in. I copied this code from my program and took out the stuff that is too specific. It is just a stub that might help you. My imp is taking data from 5 Arduinos that are all sharing the UART. As such there are collisions sometimes and I just ignore the bad data and wait for good data. that is why there is a try/catch statement in there.

`function uartHandler()
{

// This will return -1 if there is no data to be read.
while (byte != -1)  // otherwise, we keep going until there is no data
{
  


  switch (byte){
    
    case 33:

        //! 
        break;
    case 10:

    //end of line, do something with the string

    //Should be just a single character representing the machine number
    mystringout = strip(mystringout); 

    server.show(countHolder);

    try {
      MachineNumber = mystringout.tointeger();
      
    }

    catch (err) //
    {
      //If the number does not convert propertly
      //ignore the counts and times
      server.log("not an integer");
      mystringout="";
      
    }



    byte = "";
    mystringout = "";

    break;//10



  default:

     //so something with any type of character

if (byte < 128){
      	//just build the string up
      	mystringout = mystringout + format("%c",byte); 
    }

    break;
    //other characters added to the string

  }

  // read from the buffer again (not sure if it's a valid character yet)

  byte = hardware.uart57.read();  


}//end WHILE read from buffer til empty

}//end UART callback response`

Thanks for the examples. I used that split function, worked great!

Thanks.