UART API issues

I’m trying to use the imp to communicate over RS-485 using a MAX3483 (http://www.maximintegrated.com/datasheet/index.mvp/id/1079). I am using uart_12 for TX/RX and the imp’s pin5 to control transmit/receive select (DE and ~RE on the datasheet). I wasn’t successfully getting any communication to work between the imp and my Modbus device - I was getting some data but it would be truncated and the last few symbols would be wrong. So I tried connecting two imps directly together (without the MAX3483) - everything worked fine. So I tried hooking two imps and two MAX3483’s together - I had the same problem as before, truncated messages.

After inserting some log messages, everything finally worked! But, I hadn’t changed any of my actual code… Finally, I think I discovered the issue. The MAX3483 is a half duplex chip and requires driving a pin low or high to select transmit or receive mode. The key was remembering the UART is buffered on the imp and is handled by a thread in the OS, it isn’t necessarily sequential like the Squirrel code.

txControlPin.write(1); local writestr = ""; for (i = 0; i < u8ModbusADUSize; i++) { MBSerial.write(u8ModbusADU[i]); writestr += format("%.2X ", u8ModbusADU[i]); } txControlPin.write(0)

My code was turning on the Driver Enable of the MAX3483 but then turning it off before the buffer was completely written out by the UART, truncating my messages. Adding the string operations slowed down the squirrel enough to allow the OS to write the messages before the pin changed states.

I know that there are some more features coming to this class like writing strings and blobs, configuring the buffer size, and callbacks (which I can use to fix my issue). Does electric imp have any timeline information on when we can expect those features? I’d also like to add a few wishlist items such as a millis() function for more accurate or easier to implement timeouts, some functions to check the state of the uart buffers, and a uart.flush() function but those would just be gravy. =)

The things you ask for are already on the wishlist, indeed on the to-do list – except for millis(). What would that do, that’s different from either imp.sleep() or imp.wakeup()?

Peter

millis() would return the number of milliseconds since the imp began running the current program. I want to process my data as soon as its available so I’ve set up some code that looks something like this:

`u32StartTime = clock(); //Ideally millis() goes here
while (u8BytesLeft && !u8MBStatus){

local byte = hardware.uart12.read()
while(byte != -1 && u8BytesLeft)
{
  u8ModbusADU[u8ModbusADUSize++] = byte
  u8BytesLeft--;	//Once all the data is read, both loops will break
  byte = hardware.uart12.read();
}

//Process Data and verify it is valid

if (clock() > (u32StartTime + ku8MBResponseTimeout))
{
  u8MBStatus = ku8MBResponseTimedOut;	//If we've timed out, break the loop
}
//else keep trying to read data

}
`

I would like to be able to control my timeout on the millisecond level but with the current API calls I can only do it to the hundredth of a second using clock().

Peter, do you have an estimate on when I can expect a callback function for the uart finishing its write operation? Due to the MAX3483 only being half duplex, I usually end up truncating the end of the sending message or chopping off the beginning of the receiving message unless I just get lucky with the code’s timing.

Ohhh, I see. Currently the imp’s OS doesn’t have a millisecond timer, only the centisecond one that you’re already using. We have a plan for how to implement millis(), and even micros() if that’s what people want – but it won’t be soon.

The enhanced UART API including uart.flush is not likely to make it into the next release, but should be in the one after that.

Peter