10 years, 1 month ago.

Compiler Trouble??

Hi all,

Could anyone help with some trouble having with my program. I have a reading from a ultrasonic sensor (actually there are 2) and I want to view it using the websocket program.I have the websocket program working fine but when I try to put my value in (line 89) to be displayed it won't compile. I get a too many arguments in function call error. I've attached my program. Any help would be great, thank you.

Rob

#include "mbed.h"
#include "VodafoneUSBModem.h"
#include "Websocket.h"
#include "Terminal.h"

Terminal term(USBTX, USBRX);
  AnalogIn ultrasensor(p15);  
  DigitalIn range (p10);
  Timer t;
  int a,b;
  float buffer1[50]; 
  float answer, sum, result;

void test(void const*) 
{
    
    // Put 50 values from ultrasonic sensor into a buffer*************
    for ( int a=0;a<=49;a++)
    {
    buffer1[a]=ultrasensor.read();
    }
    // Set sum to zero so not using values from previous round **********
   sum=0;
   // Add together 50 values taken from ultrasonic sensor ******************
   for (b=0;b<=49;b++)
   {
   sum=sum+buffer1[b];
   }
   // Devide values by 50 to get average ***********************************
   result=sum/50;      
   answer=result*1024;
   
   // Print values in Tera Term
  // term.printf(" Voltage Value is:  %0.2f \n\r", answer);
   //wait (0.4);
   //term.cls();
 
//  ************************    Pulse Width Part of program ***********************//

//I assume here you got 'range' defined as DigitalIn on the correct pin
//Timer timer;  //Define a timer we can use
 
   while(range == 1);    //This blocks the program as long as your range pin is high.
 
//So here the range pin must be low
 
   while(range == 0);    //This blocks the program as long as your range pin is low.
 
//When we get here it means the range pin just went from low to high
t.start();             //So start measuring the time
 
//Wait as long as the pin is high:
while(range == 1);
 
//Here the output is low again, so we can stop the timer.
t.stop();
 
float time_us = t.read_us();
float cm = time_us/58;
term.printf(" Voltage Value is:  %0.2f  Pulse Width Value is: %0.2f \r", answer, cm);
//term.printf(" Pulse Width Value is: %f\r", cm);
wait(1);
t.reset();
//term.cls();
    
    
    
    
    VodafoneUSBModem modem;
    Websocket ws("ws://sockets.mbed.org:443/ws/generator/rw");
    char recv[128];
    
    int ret = modem.connect("smart");
    if(ret)
    {
      printf("Could not connect\n");
      return;
    }
    
    bool c = ws.connect();
    printf("Connect result: %s\n", c?"OK":"Failed");
    
    
    
    for(int i = 0; i < 10000; i++)
    {
        if(!(i%100))
        {
          int ret = ws.send("Generator values are:   %0.2f",answer);
          if(ret<0)
          {
            printf("Timeout\n");
            ws.close();
            c = ws.connect();
            printf("Connect result: %s\n", c?"OK":"Failed");
          }
        }
        
        if (ws.read(recv)) {
            printf("rcv: %s\r\n", recv);
        }

    }
    
    modem.disconnect();  

    while(1) {
    }
}


int main()
{
  Thread testTask(test, NULL, osPriorityNormal, 1024 * 4);
  DigitalOut led(LED1);
  while(1)
  {
    led=!led;
    Thread::wait(1000);  
  }
  return 0;
}

2 Answers

10 years, 1 month ago.

I had something similar some time ago, not using these libraries, I can't remember exactly what, but I had to generate my output data in a buffer first then send the buffer.

10 years, 1 month ago.

You're sending the formatting of a string, rather than a string, much like printf. What you need is to save the format and the data in an actual string. Look up sprintf() here.

char st[30];
sprintf( st, "Generator values are:   %0.2f", answer );
int ret = ws.send( st );

Hi, thanks for that. I read a bit about it and think I've got it. But I changed my code but the value in the websocket viewer just comes up with the same value, 251.16, constantly. It won't give me the live value from the sensor? This is the code I now have.I also get a warning about the last statement being unreachable "return 0;" ?? Not sure what this means. Any ideas? Thanks.

#include "mbed.h"
#include "VodafoneUSBModem.h"
#include "Websocket.h"
#include "Terminal.h"

Terminal term(USBTX, USBRX);
  AnalogIn ultrasensor(p15);  
  DigitalIn range (p10);
  Timer t;
 // int a,b;
  //float buffer1[50]; 
  float answer, sum, result;
  

void test(void const*) 
{
    
//  ************************    Pulse Width Part of program ***********************//

//I assume here you got 'range' defined as DigitalIn on the correct pin
Timer timer;  //Define a timer we can use
 
   while(range == 1);    //This blocks the program as long as your range pin is high.
 
//So here the range pin must be low
 
   while(range == 0);    //This blocks the program as long as your range pin is low.
 
//When we get here it means the range pin just went from low to high
t.start();             //So start measuring the time
 
//Wait as long as the pin is high:
while(range == 1);
 
//Here the output is low again, so we can stop the timer.
t.stop();
 
float time_us = t.read_us();
float cm = time_us/58;
//term.printf(" Voltage Value is:  %0.2f  Pulse Width Value is: %0.2f \r", answer, cm);
//term.printf(" Pulse Width Value is: %f\r", cm);
wait(1);
t.reset();
//term.cls();
    
    
    
    
    VodafoneUSBModem modem;
    Websocket ws("ws://sockets.mbed.org:443/ws/generator/rw");
    char recv[128];
    
    int ret = modem.connect("smart");
    if(ret)
    {
      printf("Could not connect\n");
      return;
    }
    
    bool c = ws.connect();
    printf("Connect result: %s\n", c?"OK":"Failed");
    
    
    
    for(int i = 0; i < 10000; i++)
    {
        if(!(i%100))
        {
          
        char st[30];
        sprintf( st, "Generator values are:   %0.2f", cm );
        int ret = ws.send( st );

         // int ret = ws.send("Generator values are:   %0.2f",answer);
          if(ret<0)
          {
            printf("Timeout\n");
            ws.close();
            c = ws.connect();
            printf("Connect result: %s\n", c?"OK":"Failed");
          }
        }
        
        if (ws.read(recv)) {
            printf("rcv: %s\r\n", recv);
        }

    }
    
    modem.disconnect();  
wait (5);

    while(1) {
    }
}


int main()
{
  Thread testTask(test, NULL, osPriorityNormal, 1024 * 4);
  DigitalOut led(LED1);
  while(1)
  {
    led=!led;
    Thread::wait(1000);  
  }
  return 0;

}
posted by robert heaney 29 Mar 2014

You're getting the same value each time because you've read t.read_us on line 38 just one time, so cm on line 39 will be the same every time; it's never updating. Yes, you're looping on lines 65 through 88, but that loop does not include another t.read_us call. If you want different values, you have to update time_us somewhere in the loop. Something like this - this is just pseudo code, not written and tested code:

for ( int i = 0; i < 10000; i++ ) {
  // ... stuff from your loop, here
  time_us = t.read_us();
  cm = time_us / 58;
  // ... more stuff
}

The compiler warning is from line 107: you call "return 0" but you'll never get out of the while loop starting on line 102, so the return is kind of pointless. Think of it this way: when you return from "main," where do you go? In a micro controller, there's no patiently waiting operating system to catch the return: your program runs forever. Just remove line 107 and it'll be fine.

posted by Aaron Minner 29 Mar 2014

I have that working now, thank you. I was wondering if you know how I can set how many times it will up date? I wasn't sure if there was a limit in place for how ,many times it would receive a message. And if this can be set or not? I wondered if it was done in the for loop in the program? Thanks Rob

posted by robert heaney 29 Mar 2014

Short answer: Yes, you can limit the number of times it generates data, and there are a couple of ways you can do it. You could use a for loop, much like on line 65, in your updated example.

Alternatively, in your "main" routine, you could loop there, calling "test" each time, as well. Something like this:

for ( int n = 0; n < 10; n++ ) {
  led=!led;
  Thread::wait(1000);
  test( (void *)NULL );
}

Honestly, in this case, you don't need the thread to run the test function: just call it directly from main.

But, the bigger question is: What is the module supposed to do, overall? For example, I have a micro controller that reads a temperature / barometer sensor once a minute, forever. That's all it does: read the temp / barometer, save the data so I can get at it as I want, and then wait for the next time. I'm Ok with that relatively limited behavior: I don't need that module to do anything else. What is your project supposed to do?

posted by Aaron Minner 29 Mar 2014