HTTP RPC not working

27 Mar 2011

Hi all,

I am currently working on HTTP RPC with custom variables. I have mixed HTTP server coding with my working coding. The data that i want to transmit via RPC is perfectly working via normal printf statement. Somehow it is not accessible in Labview or Java via HTTP RPC.

#include "mbed.h"
#include "EthernetNetIf.h"
#include "HTTPServer.h"
#include <string.h>
#include "RPCVariable.h"

DigitalOut led1(LED1, "led1");
DigitalOut led2(LED2, "led2");
DigitalOut led3(LED3, "led3");
DigitalOut led4(LED4, "led4");

Serial device(p13, p14);
Serial pc(USBTX, USBRX);

char addr[6],temp[6],volt[5],rsi[5]; //general for acqusition
char addr_h[6],addr_1[6],addr_2[6],addr_3[6];

char address_1,address_2,address_3,address_h;
float temperature_1,temperature_2,temperature_3,temperature_h;
float voltage_1,voltage_2,voltage_3,voltage_h;
int rssi_1,rssi_2,rssi_3,rssi_h;
int n;

LocalFileSystem fs("webfs");

EthernetNetIf eth;  
HTTPServer svr;

int main() {
    Base::add_rpc_class<AnalogIn>();
    Base::add_rpc_class<AnalogOut>();
    Base::add_rpc_class<DigitalIn>();
    Base::add_rpc_class<DigitalOut>();
    Base::add_rpc_class<DigitalInOut>();
    Base::add_rpc_class<PwmOut>();
    Base::add_rpc_class<Timer>();
    Base::add_rpc_class<BusOut>();
    Base::add_rpc_class<BusIn>();
    Base::add_rpc_class<BusInOut>();
    Base::add_rpc_class<Serial>();

  printf("Setting up...\n");
  EthernetErr ethErr = eth.setup();
  if(ethErr)
  {
    printf("Error %d in setup.\n", ethErr);
    return -1;
  }
  printf("Setup OK\n");
  
  FSHandler::mount("/webfs", "/files"); //Mount /webfs path on /files web path
  FSHandler::mount("/webfs", "/"); //Mount /webfs path on web root path
  
  svr.addHandler<SimpleHandler>("/hello");
  svr.addHandler<RPCHandler>("/rpc");
  svr.addHandler<FSHandler>("/files");
  svr.addHandler<FSHandler>("/"); //Default handler
  //Example : Access to mbed.htm : http://a.b.c.d/mbed.htm or http://a.b.c.d/files/mbed.htm
  
  svr.bind(80);
  
  printf("Listening...\n");
    
  while(true)
  {
    Net::poll();
           if(pc.readable()) 
        {
            device.putc(pc.getc());
        }
        if(device.readable()) 
        {
        
while (device.getc() != '$');
device.scanf("%4s",&addr);

while (device.getc() != ',');
device.scanf("%4s",&temp);
float tempf = atof(temp);

while (device.getc() != ',');
device.scanf("%3s",&volt);
float voltf = atof(volt);

while (device.getc() != ',');
device.scanf("%3s",&rsi);
int rsif = atoi(rsi);

{
      if ((strcmp(addr,"HUB0")==0))
      n=1;
      else if ((strcmp(addr,"0001")==0))
      n=2;
      else if ((strcmp(addr,"0002")==0))
      n=3;
      else if ((strcmp(addr,"0003")==0))
      n=4;
      else
      n=5;
}

switch(n)
{
case 1:
        strcpy(addr_h,addr);
        temperature_h = tempf;
        voltage_h = voltf;
        rssi_h = rsif ;
        break;
case 2:
        strcpy(addr_1,addr);
        temperature_1 = tempf;
        voltage_1 = voltf;
        rssi_1 = rsif ;
        break;
case 3:
        strcpy(addr_2,addr);
        temperature_2 = tempf;
        voltage_2 = voltf;
        rssi_2 = rsif ;
        break;
case 4:
        strcpy(addr_3,addr);
        temperature_3 = tempf;
        voltage_3 = voltf;
        rssi_3 = rsif ;
        break;
        
case 5: pc.printf("error");

}
RPCVariable<float> RPCtemp_h(&temperature_h, "temperature_h");
RPCVariable<float> RPCtemp_1(&temperature_1, "temperature_1");
RPCVariable<float> RPCtemp_2(&temperature_2, "temperature_2");
RPCVariable<float> RPCtemp_3(&temperature_3, "temperature_3");

RPCVariable<float> RPCvolt_h(&voltage_h, "voltage_h");
RPCVariable<float> RPCvolt_1(&voltage_1, "voltage_1");
RPCVariable<float> RPCvolt_2(&voltage_2, "voltage_2");
RPCVariable<float> RPCvolt_3(&voltage_3, "voltage_3");

RPCVariable<int> RPCrssi_h(&rssi_h, "rssi_h");
RPCVariable<int> RPCrssi_1(&rssi_1, "rssi_1");
RPCVariable<int> RPCrssi_2(&rssi_2, "rssi_2");
RPCVariable<int> RPCrssi_3(&rssi_3, "rssi_3");

printf("addr=%s temp=%f volt=%f rsi=%i \r\n",addr_h,temperature_h,voltage_h,rssi_h);
printf("addr=%s temp=%f volt=%f rsi=%i \r\n",addr_1,temperature_1,voltage_1,rssi_1);
printf("addr=%s temp=%f volt=%f rsi=%i \r\n",addr_2,temperature_2,voltage_2,rssi_2);
printf("addr=%s temp=%f volt=%f rsi=%i \r\n",addr_3,temperature_3,voltage_3,rssi_3);
}} 
 
  
  return 0;

}

Thanks, Vatsal

27 Mar 2011

Hi

Have you had success with RPC at all eg can you control the LEDs or is it just a problem with the RPCInterface library and make sure you check that the problem is on the mbed side by trying to send the RPC commands by just typing in the URL in a browser.

Try declaring the RPCVariables with the floats, at the moment your code is redeclaring them each time it runs through the loop and that could be your problem. See the motor control example on the RPC Interface Library page. eg:

char address_1,address_2,address_3,address_h;
float temperature_1,temperature_2,temperature_3,temperature_h;
float voltage_1,voltage_2,voltage_3,voltage_h;
int rssi_1,rssi_2,rssi_3,rssi_h;
int n;

RPCVariable<float> RPCtemp_h(&temperature_h, "temperature_h");
RPCVariable<float> RPCtemp_1(&temperature_1, "temperature_1");
RPCVariable<float> RPCtemp_2(&temperature_2, "temperature_2");
RPCVariable<float> RPCtemp_3(&temperature_3, "temperature_3");

RPCVariable<float> RPCvolt_h(&voltage_h, "voltage_h");
RPCVariable<float> RPCvolt_1(&voltage_1, "voltage_1");
RPCVariable<float> RPCvolt_2(&voltage_2, "voltage_2");
RPCVariable<float> RPCvolt_3(&voltage_3, "voltage_3");

RPCVariable<int> RPCrssi_h(&rssi_h, "rssi_h");
RPCVariable<int> RPCrssi_1(&rssi_1, "rssi_1");
RPCVariable<int> RPCrssi_2(&rssi_2, "rssi_2");
RPCVariable<int> RPCrssi_3(&rssi_3, "rssi_3");
LocalFileSystem fs("webfs");

EthernetNetIf eth;  
HTTPServer svr;

int main() {
......

//then just use the variables as normal within your code eg:
temperature_3 = 1.0;
....

Hopefully this will help.

Michael

27 Mar 2011

Hi Michael,

Thank you for your quick response. The code worked perfectly when i started the serial terminal application. Because every loop starts after device.readable()..

if(device.readable()) 
        {...

Is there any way that i can put everything out of that loop so everything work even when terminal application is not running.

Thanks, Vatsal

27 Mar 2011

Hi

I'm not sure what you mean by everything working perfectly when you open the serial terminal application. Do you mean you tried RPC over serial or that the printf's work as expected or that HTTP RPC works. And do you mean with or without the changes I suggested.

In your code you update the variables when your device indicates that there is a new value of the sensor readings. But the RPCVariables don't need to be updated or redefined as they are contain a reference to the float variables that you change.

By everything working when the terminal application is not running do you mean the serial device or serial on the computer. The contents of the loop will work fine without a serial application on the computer, you just won't see the output. But you do need to declare the RPCVariables outside of the loop. You could take everything outside of the loop using RPCFunctions but then they'd only read from the sensors when you call for the values. The way you are doing it at the moment appears quite sensible if results are only avaliable from the sensors at set intervals.

27 Mar 2011

Hi,

Sorry i did mistake. Actually it works perfectly without terminal application.It was just for printf statement. Actually my serial monitor software got stuck and was transmitting even after i unplugged MBED.

It worked perfectly after i made changes that you suggested. Redeclaration of variables was the only problem. I am rewriting the full code with only required parameters. Will post once completed. BTW thank you very much for support and for RPCInterface library. Very useful work indeed.

Thanks, Vatsal