Serial issue

Hi,

I’m at a loss setting up communication between Arduino Pro Mini and an Imp (Breakout board). The strange thing is: this has been working the last couple weeks. Since today: nothing.

I have added a logic level converter, my code is as follows:

`// Assign hardware
serial <- hardware.uart12;

function readSerial() {
local byte = serial.read();
local data = “”;
while (byte != -1) {
// read repeatedly, we want just the last value.
data += format("%c", byte);
byte = serial.read(); // read next byte.
}
if (data.len()) {
server.log(data);
agent.send(“data”, data);
} else {
server.log("Got nothing - " + data.len());
}
}

function executeTask() {
server.log(“Sending command!”);

// query Arduino
//serial.write(0xB0); // tried this too, no difference.
serial.write('p');
serial.flush();
//readSerial();  // now handling in callback when configuring serial.

}

// After wake-up and idle after startup do:
imp.onidle(function() {
// wait 1 more sec before going to deep sleep, making sure we have no
// unfinished business.
imp.sleep(1); // Do I need this??

//wake up every 5 mins (on the minute)
server.sleepfor(300 - (time() % 300));

});

serial.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS, readSerial);

executeTask();`

On the Arduino I have this:
`
const byte STAT1 = 7;
const byte STAT2 = 8;
const byte ARDLED = 13;

void setup()
{
Serial.begin(9600);
}

void loop()
{

// respond to imp requests.
while (Serial.available()) {
  digitalWrite(STAT2, HIGH); //Blink stat LED
  char command = Serial.read();
  // allow imp to reset timers at midnight (to sync with real time)
  if (command == 'x' || command == 0xFFFFFFA0) {
    Serial.print("%reset#");
    Serial.flush();
  }
  if (command == 'p' || command == 0xFFFFFFB0) {
    Serial.print("%pong#");
    Serial.flush();
    for(int i=0; i < 4; i++) {
        digitalWrite(STAT2, LOW); //Blink stat LED
        delay(50);
        digitalWrite(STAT2, HIGH); //Blink stat LED
        delay(25);
    }
  if (command == 'd' || command == 0xFFFFFFD0) {
    impDebug(); // Send debug to imp %.....#
  }
  digitalWrite(STAT2, LOW); //Blink stat LED
}

delay(150); // do this every 150 ms

}
`

I can see using the LED’s that the command from the imp arrives on the Arduino. They flash every 5 mins. But nothing is getting back to the imp: the serial callback is never triggered.
To troubleshoot, I ended up soldering a wire to PIN2 on the imp board and connected that to the RXI of an FTDI board. I can actually see the desired serial data in the terminal screen monitoring the FTDI! So the data makes its way all the way back to the imp card… but nothing in the code.

Any thoughts?

Thanks!
Tom.

I did not know there was a uart12. is this uart1289?

Some of the modules and imps have had poor contact on pin 1. Could the problem you are having be related to pin 1? or is your communication going through pin 2. ( I did not look closely at the code because you said the design used to work).

If pin 1 contact could cause the bad behavior you can test this by pushing the card slightly into the socket - but not so far you disengage the latch.

Thanks for your advice. I’ve made 3 changes to the code and it’s working now.

I’ve messed around with pins 1/2 some more. I could get it to work now when forcing a read from the serial port. The callback however didn’t work, so I changed to try pins 5/7. Using those pins the callback works. Not sure why - maybe I messed up my pins? I might try this on another board after this project.

Second, I was parsing information coming from the serial port with the assumption that the loop around read() would continue until all data is read. I now found that if ready more than a few chars, the callback is called several times. I’m now maintaining a buffer and looking out for start and end characters. Works perfectly.

Lastly, I used to sleep a few secs before going into deepsleep to let work finish… I believe the docs say this is a best practice to let supportive mechanisms between agent and device do their thing?? In any case, I change that with a brief wakeup construct before I go to deepsleep. That seems to work nicely.

Between potential hardware and software issues, no sure what to point my finger too. Just glad it’s working now. My device code below as fyi:

`
// Assign hardware
serial <- hardware.uart57;
buffer <- “”;
buffering <- false; // use global buffer to keep data between serial reads.
imp.setpowersave(true); // I don’t need low latency traffic.

function readSerial() {
local byte = serial.read();
while (byte != -1) {
// read repeatedly, we want just the last value.
local c = format("%c", byte);
if (byte == ‘$’ || byte == ‘%’) { // Start of sequence
buffering = true;
//server.log(“Start buffering…”);
} else if (byte == ‘#’) { // End of sequence
buffering = false;
buffer += c;
agent.send(“data”, buffer);
buffer = “”;
}
if (buffering) { // only add to buffer when buffering
buffer += c;
}
byte = serial.read(); // read next byte.
}
}

function byebye() {
server.log(“going to sleep”);
server.sleepfor(30 - (time() % 30)); // For testing
//server.sleepfor(300 - (time() % 300));
}

function executeTask() {
server.log(“Sending command!”);
// query Arduino
serial.write(‘r’);
serial.flush();

// We'll wait a little bit for tasks to be completed (e.g. read from serial).
imp.wakeup(2.0, byebye); // wake up over 2 second to go to sleep.

}

serial.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS, readSerial);

executeTask();
`

Thanks!

The best practice is to use imp.onidle() to schedule your sleep function.

If I do server.sleepfor() in imp.onidle() without waiting, won’t I miss any data that comes in as a response to the write to Arduino? It takes arduino a second or so to respond. Will imp.onidle not trigger right after the serial.write (assuming I remove the imp.wakeup()).

You can do both if you want - if it’s important to keep your imp alive for a bit of time to make sure hte Arduino is all done, you can call server.sleepfor() from within imp.onidle from within the imp.wakeup… it sounds confusing, but it’s actually not :slight_smile:

`function byebye() {
server.log(“going to sleep”);
imp.onidle(function() { server.sleepfor(30 - (time() % 30)); });
}

function executeTask() {
server.log(“Sending command!”);
// query Arduino
serial.write(‘r’);
serial.flush();

// We'll wait a little bit for tasks to be completed (e.g. read from serial).
imp.wakeup(2.0, byebye); // wake up over 2 second to go to sleep.

}`

server.sleepfor puts the imp to sleep immediately - we always want to call it from within an imp.onidle (which can be anyways) to make sure the imp gets a chance to finish what it was doing before sleeping.

Thank you, that seems like a nice optimization. I’ve added it and does the trick.