9 years, 7 months ago.

RTOS and Serial

Hello everybody First sorry for my poor English. I'm quite new to mbed and for a school project I want to use the RTOS possibility from mbed. My project is to control a robot, a modified m3pi, with a second mbed en Xbee. I managed to use picojson library to handle the communication. The next step is to use RTOS so I can control the robot and send data back to the second mbed. I wrote a simple test program to learn more about the RTOS library. My problem is reading the data. Sending works fine.

#include "mbed.h"
#include "C12832.h"
#include "MMA7660.h"
#include "LM75B.h"
//#include "mbed_rpc.h"
#include "picojson.h"
#include "rtos.h"

Serial xbee (p9, p10);

DigitalOut xbee_res (p30);
C12832 lcd (p5, p7, p6, p8, p11);
Serial pc (USBTX, USBRX);
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);
const int SIZE = 255;
string str, rvalue, rmode, raction, svalue, smode, saction, strvalue, strmode, straction;
char send[SIZE];
char data[SIZE];
char testing [SIZE +1];
char value[10],mode[10], action[10];
char test;


void parse() {
    picojson::value ledcontrol;
    const char *json = data;
 
    string err = picojson::parse(ledcontrol, json, json + strlen(json));
    //pc.printf("res error? %s\r\n", err.c_str());
    pc.printf("LED =%s\r\n" ,  ledcontrol.get("LED").get<string>().c_str());
    pc.printf("Mode =%s\r\n" ,  ledcontrol.get("Mode").get<string>().c_str());
    pc.printf("Action =%s\r\n" ,  ledcontrol.get("Action").get<string>().c_str());
    rvalue = ledcontrol.get("Led").get<string>().c_str();
    rmode = ledcontrol.get("Mode").get<string>().c_str();
    raction = ledcontrol.get("Action").get<string>().c_str();
    pc.printf("LED: %s\r\n", rvalue);
}

void serialize(char *value, char *mode, char *action) {
    picojson::object ledcontrol;
    //picojson::object inner;
    ledcontrol["LED"] = picojson::value(svalue);
    ledcontrol["Mode"] = picojson::value(smode);
    ledcontrol["Action"] =  picojson::value(saction);
    
 
    str = picojson::value(ledcontrol).serialize();
    
        
    pc.printf("serialized content = %s\r\n" ,  str.c_str());
    
}

void writeXbee_thread(void const *args)
{
    //while(1)
    //{
        while (xbee.writeable())
            {
                pc.printf("%s %s %s\r\n", value, mode, action);
                myled4 = !myled4;  
                pc.printf("Xbee writeable");
                pc.printf(send);
                xbee.printf("%s\r\n",str.c_str());
                pc.printf("Starting PicoJSONSample "__TIME__"\r\n");
                pc.printf(">>> serializing \r\n");
                serialize(value, mode, action);
                pc.printf("Ending PicoJSONSample " __TIME__ "\r\n");
                wait_ms(200);
            }
        //else
        //    lcd.printf("Xbee is bussy");
    //}       
        
        
        Thread::wait(500);
}

void readXbee_thread(void const *args)
{
    //while(1)
    //{ 
        test = xbee.getc();
        pc.printf("%c\r\n",test);
        while(xbee.readable())
            {
                myled1 = !myled1;            
                int data_size = xbee.scanf("%s\r\n", data);
                xbee.scanf("%s", data);
                pc.printf("Data size = %d \r\n",data_size);
                pc.printf("%s\r\n",data);
                pc.printf(">>> parsing \r\n");
                parse();
                wait_ms(200);
            }
        //else
        //    pc.printf("Xbee is bussy");
    //}
    Thread::wait(500);
}

void readpc_thread(void const *args)
{
    
    char *check;
    pc.printf("%c  %i", check, sizeof(check -1));
    while(sizeof(check -1) != 4)
    {
        pc.printf("Choose Led2 or Led3\r\n");
        pc.printf("Led2 = led2 and Led3= led3\r\n");
        pc.scanf("%4s", value);
        
        pc.printf("Choose to flash or switch it on\r\n");
        pc.printf("Flash = flash  or On = on\n");
        pc.scanf("%4s" , mode);
        
        pc.printf("Choose to activate or stop it\r\n");
        pc.printf("Stop = stop and Activate = start\r\n");
        pc.scanf("%4s", action);
        
    }
    
    svalue = value;
    smode = mode;
    saction = action;
    
    Thread::wait(500);
    
}

void flashing(string rvalue)
{
    while(rvalue == "led2")
    {
        myled2 = 1;
        wait_ms(200);
        myled2 = 0;
        wait_ms(200);
    }
    
    while(rvalue == "led3")
    {
        myled3 = 1;
        wait_ms(200);
        myled3 = 0;
        wait_ms(200);
    }
}

void stoping()
{
        myled2 = 0;
        myled3 = 0;
}
        

int main()
{
    xbee.baud(115200);
    xbee_res = 0; //Set reset pin to 0 
    wait_ms(1);//Wait at least one millisecond 
    xbee_res = 1;//Set reset pin to 1 
    wait_ms(1);//Wait another millisecond
    /*
    pc.printf("Choose Led2 or Led3\r\n");
    pc.printf("Led2 = led2 and Led3= led3\r\n");
    pc.scanf("%10s", value);
    pc.printf("Choose to flash or switch it on\r\n");
    pc.printf("Flash = flash  or On = on\n");
    pc.scanf("%10s" , mode);
    pc.printf("Choose to activate or stop it\r\n");
    pc.printf("Stop = stop and Activate = start\r\n");
    pc.scanf("%10s", action);
    
    svalue = value;
    smode = mode;
    saction = action;
    
    pc.printf("%s %s %s\r\n", value, mode, action);
    */
    //Thread thread(readpc_thread);
    //Thread thread1(writeXbee_thread);
    Thread thread1(readXbee_thread);

    
    
    
    
    while(1)
    {
        
    }
}

Forgot to mention with problem reading I meant: sometimes I don't receive anything, or only part of it or i receive one protocol but always the mbed freeze after it.This happens random

posted by Swen Pirker 09 Apr 2015

1 Answer

9 years, 7 months ago.

Use

RawSerial xbee (p9, p10); 
RawSerial pc (USBTX, USBRX);

instead of Serial with RTOS

...kevin

Thanks for the tip, When I use getc() I never receive the full string. I tried the following:

char te;
        char in[255];
        myled3 = 1;
        te = xbee.getc();
        myled2 = 1;
        do 
        {
            int i = 0;
            in[i] = xbee.getc();
            i++;
            wait_ms(10);
            pc.printf("%s\r\n",in);
            myled1 = 1;
        }
        while (te !='}');

I received the following: "Action":"start","LED"":"flash"} or {"Action":"start","LED":"fl or {"Action":"start","LED":"flash"} and so on. with scanf I received: {"Action":"start","LED":"led2","Mode":"flash"} an this is correct (picojson format) Also i noticed in the original program that the receiving mbed stays in xbee.readable(). I was thinking when all was received that readable() = 0. He never leaves the while(xbee.readabel()) loop. I tryed that without the thread. Why is that

posted by Swen Pirker 10 Apr 2015

Hello everybody. At the moment i could solve my problem with threads. I used the following code

void writeXbee_thread(void const *args)
{
    while(1)
    {
        writeXbee(value, mode, action);
        Thread::wait(200);
    }
}
void writeXbee(string value, string mode, string action)
{
    while (xbee.writeable())
    {
        pc.printf("%s %s %s\r\n", cvalue, cmode, caction);
        pc.printf("Xbee writeable");
        pc.printf("%s\r\n",str.c_str());
        pc.printf("Starting PicoJSONSample "__TIME__"\r\n");
        pc.printf(">>> serializing \r\n");
        serialize(value, mode, action);
        xbee.printf("%s\r\n",str.c_str());
        pc.printf("Ending PicoJSONSample " __TIME__ "\r\n");
        wait_ms(1000);
        
        if (!down)
        Thread::wait(500);
        return;
    }           
    lcd.printf("Xbee is bussy");
}
void readXbee_thread(void const *args)
{
    while(1)
    {
        readXbee();
        Thread::wait(1000);
    }
}
void readXbee()
{
    
    if(xbee.readable())
        {
            myled4 = 1;
            int data_size = xbee.scanf("%s\r\n", data);
            xbee.scanf("%s", data);
            pc.printf("Data size = %d \r\n",data_size);
            pc.printf("%s\r\n",data);
            myled4 = 0;
            wait_ms(500);
            myled4 = 1;
            pc.printf(">>> parsing \r\n");
            parse();
            myled4 = 0;
            wait_ms(10);
         }               
} 

and

int main()
{
    pc.baud(9600);
    xbee.baud(115200);
    xbee_res = 0; //Set reset pin to 0 
    wait_ms(1);//Wait at least one millisecond 
    xbee_res = 1;//Set reset pin to 1 
    wait_ms(1);//Wait another millisecond
    Thread write (writeXbee_thread);
   Thread read (readXbee_thread);
  while(1)
    {
        myled1 = 1;
        wait_ms(100);
        myled1 = 0;
        Thread::wait(500);
    }
}
posted by Swen Pirker 11 Apr 2015