Problem with strings to int conversions

Discussion in 'Arduino IDE' started by francescomm, Dec 15, 2013.

  1. francescomm

    francescomm Member

    Joined:
    Dec 14, 2013
    Messages:
    80
    Likes Received:
    4
    I have problems converting a string to an int on the Arduino IDE on the UDOO. Seems like sscanf and atoi and String.toInt do not work. They compile correctly with no errors but then lock the board at boot time (no write is displayed, even those before the instruction).

    Sample code:

    Code:
    #include <stdio.h>
    
    void setup() {
      Serial.begin(9600);
      delay(500);
    Serial.println("boot");
    }
    
    void loop() {
      int pin=0;
      
      Serial.println("ready");
    //  sscanf("1234","%d",&pin);
      Serial.println("scanf done");
      Serial.println(pin);
    
      delay(500);
    }
    
    This code works perfectly until you uncomment the sscanf line. After that, the script locks the board completely, no println istruction is shown, not even "boot" at startup.

    The defult String To Integer example (in the examples menu on the IDE) locks the arduino as well. It seems that the inclusion of the libraries themselves locks the programs at startup (or the locks the serial port?).

    I have read that there were problems with floats and that using the UDOO as an external arduino connected to another computer might solve some issues. I am wondering if a recompile/install of the ide wouldn't solve it, but what sources and how..?

    Any idea of why or a workaround? Meanwhile I'll hardcode a home made atoi() function in the code..

    Thanks,

    Francesco
     
  2. Lifeboat_Jim

    Lifeboat_Jim New Member

    Joined:
    Sep 16, 2013
    Messages:
    399
    Likes Received:
    1
    Suggested workaround (don't know if it will work) - Try using a Arduino IE on an external PC (with the patch).
     
  3. francescomm

    francescomm Member

    Joined:
    Dec 14, 2013
    Messages:
    80
    Likes Received:
    4
    Thank you, I may try that, although now I have rewritten all the str-to-int functions so it doesn't require libraries, and it actually works. Compile, flash, open serial monitor, adjust speed rate and all works, you can set/get any digital or analog pin from the serial monitor!

    Now I have another problem with the serial.. though it works quite fine in the IDE Serial Monitor, I can't find a way to print/receive to serial from linux shell/scripts, tried all the samples and googled a lot but no way, yet.

    What am i missing?? How do I take control of the serial port?

    Thanks!

    P.S: here is the code of the Sketch : https://github.com/francescom/Pilot.ino
     
  4. gokumars

    gokumars New Member

    Joined:
    Feb 22, 2014
    Messages:
    5
    Likes Received:
    0
    Thank you for posting your code in the last post, found my bug in my Arduino code.

    To make the Linux work for you the following will work.

    ubuntu@udoo:~$ sudo ln -sf /dev/ttymxc3 /dev/ttyS0
    ubuntu@udoo:~$ exec 3<>/dev/ttyS0

    #include <iostream>
    #include <stdio.h>
    #include <termios.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/objdetect/objdetect.hpp"
    #include "opencv2/gpu/gpu.hpp"
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <termios.h>
    #include <SerialStream.h>
    #include <sstream>
    #include <string>


    #include <errno.h>
    #include <termios.h>
    #include <unistd.h>

    #define height_f 240
    #define width_f 320

    using namespace std;
    using namespace cv;
    using namespace LibSerial;
    char key;
    FILE *mytempfile;

    int set_interface_attribs (int fd, int speed, int parity)
    {
    struct termios tty;
    memset (&tty, 0, sizeof tty);
    if (tcgetattr (fd, &tty) != 0)
    {
    return -1;
    }

    cfsetospeed (&tty, speed);
    cfsetispeed (&tty, speed);

    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
    // disable IGNBRK for mismatched speed tests; otherwise receive break
    // as \000 chars
    tty.c_iflag &= ~IGNBRK; // ignore break signal
    tty.c_lflag = 0; // no signaling chars, no echo,
    // no canonical processing
    tty.c_oflag = 0; // no remapping, no delays
    tty.c_cc[VMIN] = 0; // read doesn't block
    tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout

    tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

    tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
    // enable reading
    tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
    tty.c_cflag |= parity;
    tty.c_cflag &= ~CSTOPB;
    tty.c_cflag &= ~CRTSCTS;

    if (tcsetattr (fd, TCSANOW, &tty) != 0)
    {
    return -1;
    }
    return 0;
    }

    void set_blocking (int fd, int should_block)
    {
    struct termios tty;
    memset (&tty, 0, sizeof tty);
    if (tcgetattr (fd, &tty) != 0)
    {
    return;
    }

    tty.c_cc[VMIN] = should_block ? 1 : 0;
    tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout

    if (tcsetattr (fd, TCSANOW, &tty) != 0)
    {
    }

    }






    void digitalWrite(int fd, bool truth)
    {

    if(truth)
    {
    write (fd, "run\n", 4);
    }
    else
    {
    write(fd,"stop\n",5);

    }

    usleep(2000);
    char buf [1000] ="";
    char n = read (fd, buf, sizeof(buf)); // read up to 100 characters if ready to read

    char var = buf[0];
    String crap = "";
    int j = 0;
    while(j<1000)
    {
    var = buf[j];
    crap+=var;
    if(var=='\n')
    {
    j=1000;

    }
    j++;

    }
    cout<< crap;
    usleep(2000);
    }









    int main()
    {
    //setup serial
    char *portname = "/dev/ttyS0";

    int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0)
    {
    return 0;
    }

    set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity)
    set_blocking (fd, 0); // set no blocking


    waitKey(1500);
    cout << "test program" << endl;
    String whatever = "";
    usleep(2000);
    char buf_clean [1000] ="";
    char n = read (fd, buf_clean, sizeof(buf_clean)); // read up to 100 characters if ready to read
    //now flushed

    while(true)
    {
    digitalWrite(fd, true);
    sleep(2);//some delay
    digitalWrite(fd, false);

    key = cvWaitKey(1); //Capture Keyboard stroke
    if (char(key) == 27)
    {
    break; //If you hit ESC key loop will break.
    }

    }

    return 0;
    }

    Hope this helps, it's a bit rough and if anyone can help optimise it and help me remove the usleeps it would be awesome.
     
  5. gokumars

    gokumars New Member

    Joined:
    Feb 22, 2014
    Messages:
    5
    Likes Received:
    0
    The arduino code to make this work; **sorry for the fluff, it's from another project with other things going on**

    //setup for blinking led with command serial
    volatile int count = 30;
    volatile boolean toggle = false;
    volatile boolean running = false;
    volatile int laser_duty = 900;
    volatile int laser_period_us = 1000;
    String inputString = ""; // a string to hold incoming data
    String inputDigit = ""; // a string to hold incoming numberical data
    boolean stringComplete = false; // whether the string is complete


    int led = 13;//pin led is on
    //boolean flag
    //String inputString = ""; // a string to hold incoming data
    //boolean stringComplete = false; // whether the string is complete

    void setup()
    {
    // initialize serial:
    Serial.begin(115200);
    delay(500);
    // inputString.reserve(200);
    // inputDigit.reserve(200);
    Serial.println("\n[pulse_demo]");

    // reserve 200 bytes for the inputString:
    pinMode(led,OUTPUT);
    digitalWrite(led,LOW);
    Serial.println("ready to start");
    }

    void loop()
    {
    if(Serial.available())
    {




    // get the new byte:
    int inDig = Serial.read();
    char inChar = (char)inDig;
    // add it to the inputString:
    inputString += inChar;
    if(isDigit(inDig))
    {
    inputDigit += (char)inDig;
    }
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == 0xA || inChar == 0xD)
    {
    stringComplete = true;
    }



    }


    //Serial.println("ready to start");
    // print the string when a newline arrives:
    if (stringComplete)
    {
    Serial.println("you entered "+inputString);
    if(inputString.indexOf("run")!=-1)
    {
    digitalWrite(led,HIGH);
    }
    if(inputString.indexOf("stop")!=-1)
    {
    digitalWrite(led,LOW);
    }

    if(inputString.indexOf("period")!=-1)
    {

    laser_period_us = inputDigit.toInt();
    Serial.print("Laser PWM Period = ");
    Serial.print(laser_period_us);
    Serial.println(" microseconds");
    }

    if(inputString.indexOf("duty")!=-1)
    {
    laser_duty = inputDigit.toInt();
    Serial.print("Laser Duty cycle = ");
    double fraction = (double)(laser_duty)*laser_period_us/1023;
    Serial.print(fraction);
    Serial.println(" microseconds");
    }


    // clear the string:
    inputString = "";
    inputDigit = "";
    stringComplete = false;
    }
    }
     
  6. gokumars

    gokumars New Member

    Joined:
    Feb 22, 2014
    Messages:
    5
    Likes Received:
    0
    Don't forget
    ubuntu@udoo:~ exec 3>&-

    this is apparently the correct way to stop comms from the terminal.

    You can add the terminal commands in c++ code as well.
     

Share This Page