I want my multihopOscilloscope to send data through radio and Serial port as well - tinyos

I am trying to modify the multihop Oscilloscope program so that the sink node is able to send data both to UART and radio medium as well. As far as researched, I found out that the same hardware is used for sending packets via UART and radio too.
In this case, how do I modify my code so that I can send data to UART or radio based on a condition I receive. Here in the sample prorgram, I send data via radio on every 10 packets received.
The receive module for my sink node is:
event message_t* Receive.receive(message_t* msg, void *payload, uint8_t len) {
oscilloscope_t* in = (oscilloscope_t*)payload;
counter++;
am_addr_t rec = call AMPacket.source(msg);
oscilloscope_t* out;
counter++;
call Leds.led0On();
if (uartbusy == FALSE) {
out = (oscilloscope_t*)call SerialSend.getPayload(&uartbuf, sizeof(oscilloscope_t));
if (len != sizeof(oscilloscope_t) || out == NULL) {
return msg;
}
else {
memcpy(out, in, sizeof(oscilloscope_t));
}
uartlen = sizeof(oscilloscope_t);
post uartSendTask();
} else {
message_t *newmsg = call UARTMessagePool.get();
if (newmsg == NULL) {
report_problem();
return msg;
}
//Serial port busy, so enqueue.
out = (oscilloscope_t*)call SerialSend.getPayload(newmsg, sizeof(oscilloscope_t));
if (out == NULL) {
return msg;
}
memcpy(out, in, sizeof(oscilloscope_t));
if (call UARTQueue.enqueue(newmsg) != SUCCESS) {
call UARTMessagePool.put(newmsg);
fatal_problem();
return msg;
}
}
if(counter % 10 == 0){
oscilloscope_t* btrpkt = (oscilloscope_t*)(call Packet.getPayload(&pkt, sizeof(oscilloscope_t)));
call Leds.led1On();
if (call AMSend.send(rec, &pkt, sizeof(oscilloscope_t)) == SUCCESS) {
call Leds.led0On();
sendbusy = TRUE;
}
}
return msg;
}
Once the data sends back to the node from where it received the packet , it is unable to process it through UART again. Could anyone help me how could I solve my problem?

According to the question and comments:
You must instantiate AMSenderC with the same id as for the receiver. In this case, AM_OSCILLOSCOPE if you want a message to be processed by the same code. Or another id plus a new implementation of the Receive interface.
You missed putting payload into btrpkt.
You must check for sendbusy - it is a bug if you try to use the radio stack when it is busy.

Related

ESP32 serial stream freezing

I have a master device and ESP32 acting as a slave, communicating directly over UART with RX/TX cables. I've created a task that checks the serial stream every 50 ms and parses the data. My problem is that the serial stream freezes up, seemingly randomly, and only restarts if the master or the slave are restarted.
The task looks as such:
void TaskListen_UART(void *pvParameters)
{
while (true)
{
if (readSerialIn())
{
slaveRunCommand(serialData.command); // Execute received commmand
}
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}
It checks the serial stream through readSerialIn() which looks like the following:
bool readSerialIn()
{
if (UART.available() > 0) // Check if the Serial port received data
{
serialData.clearStruct(); // Clear previously saved data
if (UART.find(0x2A)) // Find "*" // Find starting delimiter
{
serialData.length = UART.read(); // Read length
if (serialData.length > BYTE_BUFFER_LEN)
{
writeSerialNACK(); // Write NACK if length seems incorrect
return false;
}
Serial.printf(("Message length: %d\n"), serialData.length);
serialData.checksum = UART.read(); // Read Checksum
Serial.printf(("Checksum: %d\n"), serialData.checksum);
if (parseBuffer(serialData.length)) // Parse the data
{
if (serialData.checkSum()) // If the checksum passes
{
serialData.assignBuffer(); // Save the parsed data to the global buffer
return true;
}
else
{
writeSerialNACK();
return false;
}
}
else
false;
}
else
return false;
}
}
The parseBuffer() function is what actually reads the stream and parses it into their according values on the slave. I tried to write it in the most fail-safe fashion, but it still hasn't cleared up my issue.
bool parseBuffer(uint8_t bufferLength)
{
uint8_t bufferPos = 0;
bool uartDetectFlag = false;
while (UART.available() > 0)
{
uartDetectFlag = true;
if (bufferPos < bufferLength)
{
serialData.serialBuffer[bufferPos] = UART.read();
}
bufferPos++;
}
if (uartDetectFlag)
return true;
else
return false;
}
At first I was suspicious that the ESP was trying to access a block in memory that doesn't exist. I noticed however that it doesn't reset itself like it normally would if that were the case, and I tried writing parseBuffer in a non-blocking manner. I also tried increasing the task delay to 100 ms, which reduced the frequency of the blocking but did not suffice in terms of speed. Regardless, it freezes up and (I think) it's caused by a large flow of data through the serial stream.

Android BLE: writing >20 bytes characteristics missing the last byte array

I have been implementing the module to send the bytes in chunks, 20 bytes each onto the MCU device via BLE. When it comes to writing the bytes more than 60 bytes and so on, the last chunk of the bytes ( usually less than 20 bytes) is often missed. Hence, the MCU device cannot get the checksum and write the value. I have modified the call back to Thread.sleep(200) to change it but it sometimes works on writing 61 bytes or sometimes not. Would you please tell me are there any synchronous method to write the bytes in chunks ? The below is my working :
#Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
try {
Thread.sleep(300);
if (status != BluetoothGatt.GATT_SUCCESS) {
disconnect();
return;
}
if(status == BluetoothGatt.GATT_SUCCESS) {
System.out.println("ok");
broadcastUpdate(ACTION_DATA_READ, mReadCharacteristic, status);
}
else {
System.out.println("fail");
broadcastUpdate(ACTION_DATA_WRITE, characteristic, status);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized boolean writeCharacteristicData(BluetoothGattCharacteristic characteristic ,
byte [] byteResult ) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
return false;
}
boolean status = false;
characteristic.setValue(byteResult);
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
status = mBluetoothGatt.writeCharacteristic(characteristic);
return status;
}
private void sendCommandData(final byte [] commandByte) {
// TODO Auto-generated method stub
if(commandByte.length > 20 ){
final List<byte[]> bytestobeSent = splitInChunks(commandByte);
for(int i = 0 ; i < bytestobeSent.size() ; i ++){
for(int k = 0 ; k < bytestobeSent.get(i).length ; k++){
System.out.println("LumChar bytes : "+ bytestobeSent.get(i)[k] );
}
BluetoothGattService LumService = mBluetoothGatt.getService(A_SERVICE);
if (LumService == null) { return; }
BluetoothGattCharacteristic LumChar = LumService.getCharacteristic(AW_CHARACTERISTIC);
if (LumChar == null) { System.out.println("LumChar"); return; }
//Thread.sleep(500);
writeCharacteristicData(LumChar , bytestobeSent.get(i));
}
}else{
....
You need to wait for the onCharacteristicWrite() callback to be invoked before sending the next write. The typical solution is to make a job queue and pop a job off the queue for each callback you get to onCharacteristicWrite(), onCharacteristicRead(), etc.
In other words, you can't do it in a for loop unfortunately, unless you want to set up some kind of lock that waits for the callback before going on to the next iteration. In my experience a job queue is a cleaner general-purpose solution though.

LwIP Netconn API + FreeRTOS TCP Client Buffer Issue

I've been trying to modify the tcp server example with LwIP in STM32F4DISCOVERY board. I have to write a sender which does not necessarily have to reply server responses. It can send data with 100 ms frequency, for example.
Firstly, the example of TCP server is like this:
static void tcpecho_thread(void *arg)
{
struct netconn *conn, *newconn;
err_t err;
LWIP_UNUSED_ARG(arg);
/* Create a new connection identifier. */
conn = netconn_new(NETCONN_TCP);
if (conn!=NULL) {
/* Bind connection to well known port number 7. */
err = netconn_bind(conn, NULL, DEST_PORT);
if (err == ERR_OK) {
/* Tell connection to go into listening mode. */
netconn_listen(conn);
while (1) {
/* Grab new connection. */
newconn = netconn_accept(conn);
/* Process the new connection. */
if (newconn) {
struct netbuf *buf;
void *data;
u16_t len;
while ((buf = netconn_recv(newconn)) != NULL) {
do {
netbuf_data(buf, &data, &len);
//Incoming package
.....
//Check for data
if (DATA IS CORRECT)
{
//Reply
data = "OK";
len = 2;
netconn_write(newconn, data, len, NETCONN_COPY);
}
} while (netbuf_next(buf) >= 0);
netbuf_delete(buf);
}
/* Close connection and discard connection identifier. */
netconn_close(newconn);
netconn_delete(newconn);
}
}
} else {
printf(" can not bind TCP netconn");
}
} else {
printf("can not create TCP netconn");
}
}
I modified this code to obtain a client version, this is what I've got so far:
static void tcpecho_thread(void *arg)
{
struct netconn *xNetConn = NULL;
struct ip_addr local_ip;
struct ip_addr remote_ip;
int rc1, rc2;
struct netbuf *Gonderilen_Buf = NULL;
struct netbuf *gonderilen_buf = NULL;
void *b_data;
u16_t b_len;
IP4_ADDR( &local_ip, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3 );
IP4_ADDR( &remote_ip, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3 );
xNetConn = netconn_new ( NETCONN_TCP );
rc1 = netconn_bind ( xNetConn, &local_ip, DEST_PORT );
rc2 = netconn_connect ( xNetConn, &remote_ip, DEST_PORT );
b_data = "+24C"; // Data to be send
b_len = sizeof ( b_data );
while(1)
{
if ( rc1 == ERR_OK )
{
// If button pressed, send data "+24C" to server
if (GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_0) == Bit_SET)
{
Buf = netbuf_new();
netbuf_alloc(Buf, 4); // 4 bytes of buffer
Buf->p->payload = "+24C";
Buf->p->len = 4;
netconn_write(xNetConn, Buf->p->payload, b_len, NETCONN_COPY);
vTaskDelay(100); // To see the result easily in Comm Operator
netbuf_delete(Buf);
}
}
if ( rc1 != ERR_OK || rc2 != ERR_OK )
{
netconn_delete ( xNetConn );
}
}
}
While the writing operation works, netconn_write sends what's on its buffer. It doesnt care whether b_data is NULL or not. I've tested it by adding the line b_data = NULL;
So the resulting output in Comm Operator is like this:
Rec:(02:47:27)+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C
However, I want it to work like this:
Rec:(02:47:22)+24C
Rec:(02:47:27)+24C
Rec:(02:57:12)+24C
Rec:(02:58:41)+24C
The desired write operation happens when I wait for around 8 seconds before I push the button again.
Since netconn_write function does not allow writing to a buffer, I'm not able to clear it. And netconn_send is only allowed for UDP connections.
I need some guidance to understand the problem and to generate a solution for it.
Any help will be greately appreciated.
It's just a matter of printing the result in the correct way.
You can try to add this part of code before writing in the netbuf data structure:
char buffer[20];
sprintf(buffer,"24+ \n");
Buf->p->payload = "+24C";
I see one or two problems in your code, depending on what you want it exactly to do. First of all, you're not sending b_data at all, but a constant string:
b_data = "+24C"; // Data to be send
and then
Buf->p->payload = "+24C";
Buf->p->len = 4;
netconn_write(xNetConn, Buf->p->payload, b_len, NETCONN_COPY);
b_data is not anywhere mentioned there. What is sent is the payload. Try Buf->p->payload = b_data; if it's what you want to achieve.
Second, if you want the +24C text to be sent only once when you push the button, you'll have to have a loop to wait for the button to open again before continuing the loop, or it will send +24C continuously until you stop pushing the button. Something in this direction:
while (GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_0) == Bit_SET) {
vTaskDelay(1);
}

With node.js HTTP, how does res.end() guarantee a disconnection of the socket?

This is node.js' end implementation:
OutgoingMessage.prototype.end = function(data, encoding) {
if (this.finished) {
return false;
}
if (!this._header) {
this._implicitHeader();
}
if (data && !this._hasBody) {
console.error('This type of response MUST NOT have a body. ' +
'Ignoring data passed to end().');
data = false;
}
var ret;
var hot = this._headerSent === false &&
typeof(data) === 'string' &&
data.length > 0 &&
this.output.length === 0 &&
this.connection &&
this.connection.writable &&
this.connection._httpMessage === this;
if (hot) {
// Hot path. They're doing
// res.writeHead();
// res.end(blah);
// HACKY.
if (this.chunkedEncoding) {
var l = Buffer.byteLength(data, encoding).toString(16);
ret = this.connection.write(this._header + l + CRLF +
data + '\r\n0\r\n' +
this._trailer + '\r\n', encoding);
} else {
ret = this.connection.write(this._header + data, encoding);
}
this._headerSent = true;
} else if (data) {
// Normal body write.
ret = this.write(data, encoding);
}
if (!hot) {
if (this.chunkedEncoding) {
ret = this._send('0\r\n' + this._trailer + '\r\n'); // Last chunk.
} else {
// Force a flush, HACK.
ret = this._send('');
}
}
this.finished = true;
// There is the first message on the outgoing queue, and we've sent
// everything to the socket.
if (this.output.length === 0 && this.connection._httpMessage === this) {
debug('outgoing message end.');
this._finish();
}
return ret;
};
Source: https://github.com/joyent/node/blob/master/lib/http.js#L645
Apparently, the connection is only "finished" when output.length === 0.
So, if there is still data waiting to be written, and the receiving client for some reason is dodgy about receiving this data, will the request ever be ended?
I have also seen such issue where an end is not effective while trying to end a http request made by a flash uploader. I ended up doing the following, which did help:
res.end(failureJSON, 'utf8');
req.once('end', function _destroyConn() {
req.connection.destroy();
});
Seems very hackish. Anyway, is such behavior with req.connection.destroy needed to guarantee a disconnection from the socket?
Unfortunately, res.end() does not directly “guarantee a disconnection of the socket” because it needs to account for HTTP Keep-Alive. According to the docs, end tells the server that everything has been sent, and that the response is complete. It’s entirely up to the server object whether or not to disconnect immediately.
To answer your question more specifically, the important thing is that the response needs to emit a finish event. If you take a look at the implementation of _finish(), it pretty much just emits the event.
As you noted though, it doesn’t always call _finish() directly…but it did set this.finished = true. When _flush() executes, it sends any remaining data and THEN calls _finish().
It’s kind of complicated, and I don’t think I can go into any more detail without the risk of being wrong.
As far as connections sometimes not closing, have you checked if you have keep-alive configured properly? If the HTTP connection is set up with keep-alive by default, then calling end will not close the socket.
If your print out res.shouldKeepAlive, it will tell you if your server is trying to use keep-alive. Set it to false at the start of your request handler if you want to stop the server from doing this.
I don't know if this helps you as I am building my framework for node 4.4+ but I have confirmed that you can send Connection: close header in your response to get node to close the connection.
let res = getResponseSomehow()
res.statusCode = 408
res.setHeader("Connection", "close")
res.end()
Also your destroy code could use the following tweak:
// First we give node the time to close the connection
// We can give it 2 seconds
let socket = getSocketSomehow();
let timer = setTimeout(function() {
socket.destroy();
}, 2000);
socket.on("close", function() {
clearTimeout(timer);
});
I'm not quite sure if it's the close event you want. I normally try to use a library and stay away from the net api so this is just a guess.

Serial port dropping data with Readline()

I am using serial port to read the data off the scale that is attached to the thin client. In 99% of cases the data is read correctly - ie whatever is on the scale is what is captured by the application.
However, sometimes, it looks like data is dropped. For instance instead of 90.007 it will be read as 0.007. I am using ReadLine function:
private void CaptureWeight()
{
globalCounter++;
string value = "";
_sp.DiscardInBuffer();
while (!this._processingDone)
{
try
{
value = this._sp.ReadLine();
if (value != "")
{
if (value == "ES")
{
_sp.DiscardInBuffer();
value = "";
}
else
{
this.Invoke(this.OnDataAcquiredEvent, new object[] { value });
}
}
}
catch (TimeoutException)
{
//catch it but do nothing
}
catch
{
//reset the port here?
MessageBox.Show("some other than timeout exception thrown while reading serial port");
}
}
} //end of CaptureWeight()
Don't call DiscardInBuffer. The operating system buffer is filled asynchronously as data is shifted in through the UART. Read all of the data and act on it accordingly because you have no way of knowing what is in the buffer at the time you discard it!
When does "ES" come? It is theory possible that the value immediately after "ES", is not read correctly, because you call DiscardInBuffer(). If in that time the buffer contains part of the next reading, e.g. the 9 in 90.007, the 9 gets discarded and you read 0.007.
Try discarding only everything before the last CR LF. But leave incomplete lines.

Resources