I took the simple serial example and tried to remove the write part. To my surprise the read part stops working. Why is this ? I am missing something obvious I think…
Anytime I comment out the call to the write function, it won’t read anymore.
`function write(writeStr)
{ //server.log(writeStr)
local serialConn = hardware.uart57
serialConn.write(writeStr.tostring());
}
function read()
{
//local output = OutputPort(“string”);
local serialConn = hardware.uart57 //This should be whatever UART you are using and should already have been configured with baud rate, parity, etc.
local readBuffer = blob(1);
local byte;
local byteIndex = 0;
local str = “”;
while((byte=serialConn.read())!=-1)
{
readBuffer.writen(byte, 'b'); //Can comment if you don't want to use the blob
//server.log(format("Byte %d = %d = 0x%2X = %c", byteIndex++, byte, byte, byte)); //Can comment if you don't want individual byte logging
str += byte.tochar(); //Converts integer read by UART into ASCII char for string representation
}
if(str.len() > 0)
{ //Function may get called by callback when no data is present - no need to log
server.log("Read String Representation = " + str)
}
//return readBuffer.tostring(); //Convenience method provided by Electric Imp not present in standard squirrel OR on the device in Release 14.
return str;
}
//local output = OutputPort(“number”); //imp.configure(“Simple Serial”, [], [], {});
hardware.uart57.configure(115200, 8, PARITY_NONE, 1, NO_CTSRTS, read.bindenv(this));
//Write data to the UART every 5 seconds
loop <- 0
function writeLoop()
{
write("Loop - " + loop++ + “\r
”);
imp.wakeup(5.0, writeLoop);
}
writeLoop();
`
Write is not required for read to work. Why did you comment out the imp.configure? You also do not need read.bindenv(this) as this isn’t a class - just use read in the configure.
The imp.configure was commented out by accident.
ok, so If I remove the entire write function and write loop it should work ? I wonder if it’s something on my arduino then ? it doesn’t read anything unless I do the write…
I will try again.
imp is 3.3V and Arduino is 5V. Do you have a level shifter and have you tested it? You could also try a lower speed at first such as 9600 until you prove that works, then work on speeding it up.
for some reason it does not workk that way.
I am wondering if the level sifter is not working right… kind of odd it would work ok if I send data as well.
almost like the tx is feeding the rx as well?
So I hooked up another arduino mega I had laying around and got the same results.
Then I hooked up an arduino uno. Reading serial seems to work fine.
The only difference is that I use hardware rx/tx on the arduino mega. Would this be an issue? Any way you can test it on a mega?
I’m afraid not, don’t have anything like that. I’d be suspicious that you have the mega configured as having a different xtal which would mean baudrates were off?
Well, I resolved the issue. It ended up being a stupid coding mistake on the arduino end. All working well.
I do have a question about the callbacks. When do they exactly work ? Is it for each byte that is read in ? If that is the case, I could only read in one byte at a time in the function the callback uses…correct? What happens if I read multiple bytes in ? Does the callback run for each byte ?
There’s an 80-byte (software) FIFO. The callback runs any time there’s data in the FIFO and Squirrel isn’t doing anything else. So the usual pattern is, keep reading bytes in the callback until the FIFO is empty (read() returns -1). If you don’t read all the bytes, your callback will get called again straightaway.
Thanks for that. What would be the best approach to read 3 strings coming in that are about 75 bytes each ?
If I currently read them all in, I seem to lose part of the string.
Well, hopefully there’s something that tells you when you’ve got to the end of one of your 75-byte strings (a newline character, for instance). If that’s the case, you can just have a global variable containing the “string so far”, and in your UART callback, append bytes to it until you see the end-of-string marker.
If you’re losing part of a string, perhaps your code is busy for more than 80 characters’ worth of time, and the FIFO is filling up?
I checked, sure enough, the first string I read in is 75 bytes
The second one is 26 bytes. The rest of it is missing.
The third one is completely missing.
How can I get around this ?
Is the imp just not meant to read in more data? Can I increase that buffer ?
Here is the code;
`function readArduino()
{
//local readBuffer = blob(1);
local byte;
local byteIndex = 0;
local str = “”;
server.log(“readArduino”)
while((byte=hardware.uart57.read())!=-1)
{
//readBuffer.writen(byte, 'b'); //Can comment if you don't want to use the blob
//server.log(format("Byte %d = %d = 0x%2X = %c", byteIndex++, byte, byte, byte)); //Can comment if you don't want individual byte logging
str += byte.tochar(); //Converts integer read by UART into ASCII char for string representation
if (byte.tochar() == "\
")
break; // break so that the callback will read the next string in… or should
}
if(str.len() > 0)
{ //Function may get called by callback when no data is present - no need to log
server.log("Read String Representation long "+ str.len() + " ->> " + str)
}
//return readBuffer.tostring(); //Convenience method provided by Electric Imp not present in standard squirrel OR on the device in Release 14.
return str;
}
imp.configure(“ReadArduino”, [], [], {});
hardware.uart57.configure(256000, 8, PARITY_NONE, 1, NO_CTSRTS, readArduino);
`
256,000baud means that the FIFO fills up in about 3ms. If you do anything in your callback that takes longer than 3s, you’ll lose data. That might include server.log(). Are the three 75-character strings sent back-to-back? If so, you want something like:
lines <- []; s <- ""; function readArduino() { local byte; while ((byte = hardware.uart57.read()) != -1) { s += byte.tochar(); if (byte.tochar() == "\ ") { lines.append(s); s = ""; } if (lines.len() == 3) { server.log("Got 'em:"); server.log(lines[0]); server.log(lines[1]); server.log(lines[2]); lines = []; } } }
The strings are sent back to back. I am testing it with 3… but the idea is to eventually send over an entire file with possibly hundreds of these lines.
It is basically an end-of-day report.
My example is not doing anything, but my idea was to send them all to the agent and the agent posts them to my webservice.
I made a work around for this.
I have the arduino send over a string, then have the imp send the same string back.
The arduino won’t send the next string until it has received the full string.
This way It can also check if it came over correctly.
I test this up to 1000000 baud rate and it works correctly.
Generally, if you’re sending a lot of data you do want some sort of ACK system. You don’t necessarily need to send the whole string back, but a “go ahead” indication is useful to allow the imp time to send the data up to the server.
I took the simple serial example and tried to remove the write part.
What serial example are you talking about? I am looking for a simple way to send bytes back and forth between an arduino and the imp. Can you point me to a working example of code on both sides of that?