1289 uart and wakeup

We configured our PWB to use the 1289 UART on imp001. Because of powersupply issues I need to deepsleep very often.

Can I use pin 1 as a wake up with this configuration if I have configured the UART with no cleartosend? As follows:

xxx.configure(9600,8,PARITY_NONE,1,NO_CTSRTS,xxxData);

Yes, configuring uart1289 with NO_CTSRTS leaves pins 1 and 2 in their existing configuration.

Peter

thanks Peter! now I don’t have to rework these boards! whew!

I have a follow on question for this as this seems to be having timing issues getting data.

The sending device takes Pin1 high then starts sending data to the UART. Sometimes when the IMP wakes, the UART callback doesn’t seem to run. I am wondering if there are any timing constraints with doing this?

Should it be staying a special state at wakeup waiting for the UART data, or will the configure callback get it?

When the imp goes to deep sleep and wakes up again – whether from the deep-sleep timer expiring or from the wake-up pin going high – then it starts again from the top of the Squirrel code, having forgotten everything. Well, it hasn’t forgotten the “nv” table if any, but it’s forgotten everything else, including that a UART callback was ever set. So you should make sure that the UART is configured again (with the callback) as soon as possible after the Squirrel program starts – for instance, without any intervening server.log() etc which would pause while it starts up the WiFi.

The latency from pin1 going high to Squirrel starting to run is very small, in the milliseconds.

Peter

I’m stumped here. The embedded controller sends a string to the uart. Its taking Pin1 high and then sending data. I have stripped everything down to this (edited to correction code)
`
s <-“X”;
c <- 0;
function EMBData()
{
// Read the UART
local b;
while ((b=EMB.readstring()) != “”)// As long as UART read value is not nothing, we’re getting data
{
c = c+1;
s = s+b;
}
server.log(“here:” + b+ “,”+s);
}
// UART config
hardware.pin1.configure(DIGITAL_IN_WAKEUP);
EMB <- hardware.uart1289;
EMB.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS, EMBData);

imp.onidle(function() {
server.log(“Nothing to do, going to sleep= “+c+” uart_flags”+EMB.flags());
server.sleepfor(200);
});

if (hardware.wakereason() == WAKEREASON_PIN1){ EMBData();}// if awoke by pin1 then check for uart data
else {server.log (“Deep Sleep Expired”);}`

It gives me this in response:

2015-03-26 16:58:29 UTC-5 [Status] Device connected; 2.38% program storage used
2015-03-26 16:58:29 UTC-5 [Device] here:,X
2015-03-26 16:58:29 UTC-5 [Device] here:,Xl
2015-03-26 16:58:29 UTC-5 [Device] Nothing to do, going to sleep= 1 uart_flags64

Two questions:

  1. how can the server.log “here” hit twice and if it does how does this account for the single “l” character on the second without it showing in b.
  2. what is the uart flag 64 really telling me?

What is the embedded controller sending? How long is it waiting before raising pin 1 and sending the data?

You’re seeing two "here"s because two bytes are being received, with enough delay between them that the handler is executing and reading the first byte, then being retriggered.

Thanks @Hugo for the help. It is really appreciated, as I am getting pretty frustrated with this and squirrel.

The embedded controller is sending ‘hello world’ as a test. Sounds simple enough. There was a problem with the transmitting uart and the pin1 timing which has been fixed.

Squirrel seems to get stuck in a loop continual callback loop to the EMBData function.

I have commented out the server.sleepfor and the entire hardware.wakereason if statement at the bottom. And this is the result.

Here is the latest output: 2015-03-27 13:30:08 UTC-5 [Device] here:H,H 2015-03-27 13:30:08 UTC-5 [Device] here:e,He 2015-03-27 13:30:08 UTC-5 [Device] here:l,Hel 2015-03-27 13:30:08 UTC-5 [Device] here:l,Hell 2015-03-27 13:30:08 UTC-5 [Device] here:o,Hello 2015-03-27 13:30:08 UTC-5 [Device] here: ,Hello 2015-03-27 13:30:08 UTC-5 [Device] here:W,Hello W 2015-03-27 13:30:08 UTC-5 [Device] here:o,Hello Wo 2015-03-27 13:30:08 UTC-5 [Device] here:r,Hello Wor 2015-03-27 13:30:08 UTC-5 [Device] here:l,Hello Worl 2015-03-27 13:30:08 UTC-5 [Device] here:d,Hello World 2015-03-27 13:30:08 UTC-5 [Device] here: ,Hello World 2015-03-27 13:30:08 UTC-5 [Device] here: ,Hello World

At this point I cannot tell what the squirrel is doing but the onidle is not activating, so its still doing something. Why would the configure callback be going to the EMBData function?

Is there a way I can terminate the EMBData function or callback when I have enough characters? Could I configure pin 8 and 9 as inputs after the correct number of characters are received?

Also I tried to configure the uart without a callback (documentation says it is optional) so I could only call the EMBData function is needed, but the checker doesn’t like it.

Any ideas are most appreciated.

Is it possible that the server.log in the uart read while loop is causing problems with framing and timing?

So the code appears to be collecting the entire string as expected. Firstly, are you seeing anything wrong there?

You do not need to have the wakereason check calling EMBData(). You have already registered a callback when you configured the UART - if data arrives, it will be called.

Your server.log will, upon wake, be blocking until wifi has connected. Remember when you wake from sleep, wifi is not connected and so the first call will block until it comes up (with the default SUSPEND_ON_ERROR settings).

I currently have two problems:

  1. The EMBData is being continually called even after the entire string is received. The result being that onidle does not reactivate (or doesn’t seem to). It just sits there at a blank server.log.
  2. The second problem is that the received string has suddenly started to be displayed as a binary in response to the server.log so that string I included above is now shown as
    binary: 4e 6f 74 68 69 6e 67 20 74 6f…

Help is greatly appreciated!

If a non-ascii character is being received, the string isn’t printable and hence the server.log will print it as binary. Look for a byte value <0x20 (maybe cut and paste one of these log messages?)

If EMBData is continually called, then that means there’s still data being received, triggering the callback. The data may not be printable, but it’s still being received.

Im sure the EMBData is being continually called back, but when I run the data through and FTDI board and putty, the data is sent correctly every time. There is no other data.

How do you know EMBData is being continually called? Can you cut and paste one of these messages where it shows binary? Noise on the serial line may be misinterpreted as a start bit, which will generally give you 0xff’s being received.

I’d forget the string stuff and actually dump the hex of every received byte, eg:

function EMBData() { local x; while((x=EMB.read()) != -1) { server.log(format("got %02x", x)); } }

…and then paste the entire output you’re seeing from a single transmit of the arduino.

Hugo: Thanks very much for your assistance. It is GREATLY appreciated!

I’m running an agent integration test so I can’t drop your code in yet. But I will do that right after I finish.

I know EMBData is being continually called because
`s <-"";
function EMBData()
{
local b =EMB.readstring();
s = s+b;
}
// UART config
hardware.pin1.configure(DIGITAL_IN_WAKEUP);
EMB <- hardware.uart1289;
EMB.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS,EMBData);

imp.onidle(function() {
server.log(“Nothing to do, going to sleep”);
server.sleepfor(200);
}); `

Never detects idle and sleeps.

Its from an MSP430 not arduino, but Im not sure that matters.
Here is the output.

2015-03-28 15:13:56 UTC-5 [Device] got 31 2015-03-28 15:13:56 UTC-5 [Device] got 2c 2015-03-28 15:13:56 UTC-5 [Device] got 30 2015-03-28 15:13:56 UTC-5 [Device] got 2c 2015-03-28 15:13:56 UTC-5 [Device] got 30 2015-03-28 15:13:56 UTC-5 [Device] got 37 2015-03-28 15:13:56 UTC-5 [Device] got 32 2015-03-28 15:13:56 UTC-5 [Device] got 2e 2015-03-28 15:13:56 UTC-5 [Device] got 30 2015-03-28 15:13:56 UTC-5 [Device] got 2c 2015-03-28 15:13:56 UTC-5 [Device] got 30 2015-03-28 15:13:56 UTC-5 [Device] got 37 2015-03-28 15:13:56 UTC-5 [Device] got 31 2015-03-28 15:13:56 UTC-5 [Device] got 2e 2015-03-28 15:13:56 UTC-5 [Device] got 35 2015-03-28 15:13:56 UTC-5 [Device] got 2c 2015-03-28 15:13:56 UTC-5 [Device] got 30 2015-03-28 15:13:56 UTC-5 [Device] got 37 2015-03-28 15:13:56 UTC-5 [Device] got 39 2015-03-28 15:13:56 UTC-5 [Device] got 2e 2015-03-28 15:13:56 UTC-5 [Device] got 30 2015-03-28 15:13:56 UTC-5 [Device] got 2c 2015-03-28 15:13:56 UTC-5 [Device] got 30 2015-03-28 15:13:56 UTC-5 [Device] got 37 2015-03-28 15:13:56 UTC-5 [Device] got 38 2015-03-28 15:13:56 UTC-5 [Device] got 2e 2015-03-28 15:13:56 UTC-5 [Device] got 35 2015-03-28 15:13:56 UTC-5 [Device] got 2c 2015-03-28 15:13:56 UTC-5 [Device] got 31 2015-03-28 15:13:56 UTC-5 [Device] got 30 2015-03-28 15:13:56 UTC-5 [Device] got 30 2015-03-28 15:13:56 UTC-5 [Device] got 2e 2015-03-28 15:13:56 UTC-5 [Device] got 30 2015-03-28 15:13:56 UTC-5 [Device] got 0d 2015-03-28 15:13:56 UTC-5 [Device] got 0a 2015-03-28 15:13:56 UTC-5 [Device] got 00

I’m afraid I can’t replicate your problem; onidle() always gets called for me: in fact, it likely triggers too early to actually see received serial, so I’ve had to comment out the sleep (so it just logs that it’s going to sleep). Are you sure you’ve attached ALL the code that is running? Other things can prevent onidle() from firing, but not the code you attached.

You might want to try this code that I just wrote. It wakes on pin 1, then waits for serial data. If nothing is received within 1s, then it sleeps again. If data is received, it accumulates it until no data is received for 0.5s, then prints it and sleeps.

I’ve tried this myself and it works fine.

`
// This code wakes on pin 1 and then waits for up to 1s for serial data to
// start being received. When data starts to flow, the code will keep receiving
// data until there’s a break of 0.5s.
//
// It will then log the serial data and sleep again. Note that the WiFi link
// does not come up until the device is about to sleep (it is in a shallow wake
// mode until the server.log).

s <-"";
sleeptimer <- null;
now <- hardware.millis();

// Empty buffer, accumulate it
function EMBData() {
s += EMB.readstring();

// If we have anything in there, then reset sleep timer to trigger
// after 0.5s with no serial data received
if (s != "") {
    if (sleeptimer != null) imp.cancelwakeup(sleeptimer);
    sleeptimer = imp.wakeup(0.5, sleepnow)
}

}

function sleepnow() {
imp.onidle(function() {
now = hardware.millis() - now;
server.log(“awake for “+now+“ms, got string '”+s+”’, going to sleep”);
server.sleepfor(200);
});
}

// UART config
hardware.pin1.configure(DIGITAL_IN_WAKEUP);
EMB <- hardware.uart1289;
EMB.configure(1200, 8, PARITY_NONE, 1, NO_CTSRTS, EMBData);

// Set an initial timeout of 1s for data
sleeptimer = imp.wakeup(1.0, sleepnow);
`

Executive summary:
How long does it take the IMP to wake up and start monitoring the UART?
How long should the sending device wait after taking PIN1 high to begin sending data?

Back ground
Lets forget about all the other problems. I can conditional a server.sleepfor when the data is complete or copy the function setup in your code. I can also strip the 00h at the end of the send to make the conversion to ascii correct.

The stopper problem I cannot manage is wakeup on pin 1 then read the UART.

I know it is sending correctly because:
-putty with FTDI = 1,0,072.0,071.5,079.0,078.5,100.0
-awake imp UART=1,0,072.0,071.5,079.0,078.5,100.0 (my code strips the trailing 00h)
-IMP wake up and read=72 aa 62 82 ba ca 72 82 62 82 ba c2 72 aa 62 8a 82 82 72 82 6a 0a 00

the code you posted returns this:
2015-03-29 16:43:31 UTC-5 [Device] awake for 529ms, got string '23', going to sleep 2015-03-29 16:43:31 UTC-5 [Device] binary: 72 aa 62 82 ba ca 72 82 62 82 ba c2 72 aa 62 8a 82 82 72 82 6a 0a 00 2015-03-29 16:43:31 UTC-5 [Device] sleeping until 1427665611000

FYI its actually 36 with the trailing 00h.

when I mod your code and comment out the server.sleep for as follows: `

function sleepnow() {
imp.onidle(function() {
now = hardware.millis() - now;
server.log(“awake for “+now+“ms, got string '”+s+”’, going to sleep”);
//server.sleepfor(200); //STAYS AWAKE FOR THE NEXT SEND
});
}
`

the response is 2015-03-29 16:51:08 UTC-5 [Device] awake for 1007ms, got string '0', going to sleep 2015-03-29 16:51:08 UTC-5 [Device] 2015-03-29 16:52:43 UTC-5 [Device] awake for 98659ms, got string '36', going to sleep 2015-03-29 16:52:43 UTC-5 [Device] binary: 31 2c 30 2c 30 37 32 2e 30 2c 30 37 31 2e 35 2c 30 37 39 2e 30 2c 30 37 38 2e 35 2c 31 30 30 2e 30 0d 0a 00

The last line show binary because of the trailing 00h which is put in for end of string.
Removing the 00h makes it converts correctly to 1,0,072.0,071.5,079.0,078.5,100.0.

My code (which is considerably different from yours) is the same. Awake for send = OK. Wake up and read = not ok.

Our system currently takes PIN1 high and waits 5mS before sending data. I have tried 500mS and 1mS. The results were roughly the same with not enough data received after a wakeup. (although the data string received was different in each case)

So, you’re changing the code here. My code is logging the string in quotes, yours appears to be printing something else (the length?). Harder to debug if you keep changing code without posting it.

You should be to the point of running code on the imp within ~10ms of the rising edge of pin 1. If you start sending data when the UART is not configured, then it will take the next falling edge on pin 9 as a start bit and, well, you’ll get junk.

500ms is far more than necessary but should have worked fine. I tested the above code myself and know it works fine; maybe post a scope plot of pin1 and the uart data? Seems like there may be something fishy going on with the incoming bitstream from the arduino?

I think part of the problem is imp.onidle – especially at low baud rates such as 1200, the imp can quite easily go idle in-between each character. “Idle” doesn’t necessarily mean “reception finished”. Hugo’s code deals with that, by using a rescheduled wakeup to ensure that the imp only sleeps once it’s been idle for a certain length of time. If you’re still having trouble, perhaps that length of time (the “0.5” about twenty lines into Hugo’s code) needs to be increased.

Peter