Shop Learn
PropGCC coding advice — Parallax Forums

PropGCC coding advice

I got a little bit of a mental block. The code below, I want to have the SIRC active and the readStr() code active.

I know the readStr() will sit there and wait, until something comes in, how do I get around that. That particular list of commands does not have a reaStr() with a timer. Anybody know of a work around or a different solution?

Thanks
Ray

int main()                                    // Main function
{
  // Add startup code here.
  drive_speed(0,0);  // Start servos/encoders
  rpi = fdserial_open(0, 1, 0, 115200);
  pause(150);

  while(1)
  {
    // Add main loop code here.
    int button = sirc_button(11);

    if(button == CH_UP) // Forward
    {
      botFore();
    }
    else if(button == CH_DN)  // Backward
    {
      botBack();
    }
    else if(button == VOL_DN)  // Left
    {
      botLeft();
    }
    else if(button == VOL_UP)  // Right
    {
      botRite();
    }
    else if(button == MUTE) // Stop
    {
      botStop();      
    }
    else
    {
      readStr(rpi,inBuff,40);
      if(!strcmp(inBuff,"s"))
      {
        botStop();
      }      
      else
      {
        writeStr(rpi,"???\n");
      }          
    }      

  }  
}

Comments

  • You can use the fdserial functions, such as fdserial_rxCheck, fdserial_rxReady, fdserial_rxTime or fdserial_rxCount to do non-waiting reads.

  • RsadeikaRsadeika Posts: 3,565

    Thanks Dave. I gave those a try, and they do not seem to want to work. When I use the readStr(), that works with the Python program, but when I try the fdserial_rxTime, that does not want too communicate.

    If I remember correctly, back some time ago, I ran into the same problem, and I ended up using readStr(), to make it work work. Their is something about the fdserial_xxx commands that I am not able to figure out. The fdserial_xxx commands are handling the incoming in a different manner. I wonder why their wasn't a readStr() with a timer capability developed a the same time.

    Ray

  • readStr uses rxChar, which uses fdserial_rxCheck, so it seems like it should work. The fdserial_rx... routines don't echo the received characters, so if you need them to echo you would need to call the transmit function explicitly.

  • AribaAriba Posts: 2,481
    edited 2021-05-11 23:15

    something like that: (?)

       ...
        else
        {
          if((c=fdserial_rxCheck(rpi)) >= 0)   //a character received?
          {
            if(c<=13) c=0;               //endcharacter: CR or LF
            inBuff[idx++] = c;           //store into string
            if(c==0 || idx>39)           //if done, or overflow:
            {
              idx=0;                     //prepare for next string rcv
              if(!strcmp(inBuff,"s"))    //check string
              {
                botStop();
              }      
            }
          }
    
  • RsadeikaRsadeika Posts: 3,565

    Thanks Ariba for the code example.

    Now I am not sure what is going on. In the code below, I have the SIRC part blocked out, the program works as expected. When I have the fdserial_rxCheck... code block blocked out and I have the SIRC block unblocked, the program works as expected. When I have both parts unblocked, only the SIRC part works as expected, the fdserial_rxCheck... does not respond. I am not sure why when both are implemented, that only the SIRC part works. What am I missing here?

    Ray

    /*
      p101bot_test.c
    
    */
    #include "simpletools.h"
    #include "fdserial.h"
    #include "simpletext.h"
    #include "sirc.h"
    #include "abdrive360.h"
    serial *rpi;
    
    
    /* bot motor */
    int speed=30;
    
    void botStop();
    void botFore();
    void botBack();
    void botLeft();
    void botRite();
    
    int main()                                    // Main function
    {
      // Add startup code here.
      drive_speed(0,0);  // Start servos/encoders
      rpi = fdserial_open(0, 1, 0, 115200);
      pause(150);
    
      char inBuff[40];
      int c,idx;
    
      while(1)
      {
        if((c=fdserial_rxCheck(rpi)) >= 0)
        {
          if(c<=13) c=0;               //endcharacter: CR or LF
          inBuff[idx++] = c;           //store into string
          if(c==0 || idx>39)           //if done, or overflow:
          {
            idx=0;                     //prepare for next string rcv
            if(!strcmp(inBuff,"s"))    //check string
            {
              botStop();
            }     
            else if(!strcmp(inBuff,"f"))
            {
              botFore();
            }
            else if(!strcmp(inBuff,"b"))
            {
              botBack();
            }
          }                   
        }
        /*else
        {   
          int button = sirc_button(11);
    
          if(button == CH_UP) // Forward
          {
            botFore();
          }      
          if(button == CH_DN)  // Backward
          {
            botBack();
          }
          if(button == VOL_DN)  // Left
          {
            botLeft();
          }
          if(button == VOL_UP)  // Right
          {
            botRite();
          }
          if(button == MUTE) // Stop
          {
            botStop();      
          }
        }*/                         
      }  
    }
    /******************************/
    
    void botStop()
    {
      drive_speed(0,0);
    }  
    
    void botFore()
    {
      drive_speed(-speed,-speed);  
    }  
    
    void botBack()
    {
      drive_speed(speed,speed);
    }  
    
    void botLeft()
    {
      drive_speed(-8,8);
    }
    
    void botRite()
    {
      drive_speed(8,-8);
    }
    /********************/
    
  • RsadeikaRsadeika Posts: 3,565

    Today I tried the putting the SIRC code in front of the fdserial code, same problem, the the SIRC works but the fdserial is not responding. Also something new occurred, after letting the bot sit for about five minutes, all of a sudden the bot started to move on its own. I have not coded any AI into the program, so not sure what too think about this.

    I am now wondering if their is a conflict that is occurring between the SIRC command and the fdserial command. Since it is the SIRC that is being dominant, maybe their is something in the SIRC structure that is causing the problem. I am not a professional C coder, so I am only guessing at this point.

    Ray

  • Post all of your code and maybe we can find the problem.

  • AribaAriba Posts: 2,481

    If the SIRC code waits until something is received from the remote control, then the further code has no chance to check for serial input. Maybe you can start the SIRC in another cog and use a common variable to report the received keys to the main code.

  • RsadeikaRsadeika Posts: 3,565

    That is what it looks like, SIRC has its own 'wait' function.

    I did put the SIRC code into its own COG, and now everything works as expected. I am trying to minimize the amount of COGs that I am using, not sure how many separate COGs I will need, as my program gets larger.

    Next I will be adding some Pings, I hope the Pings do not need a separate COG to function. Now that I have the 'wait' resolved in the fdserial code I guess I will be able to get that main() nCOG loaded up.

    Thanks
    Ray

  • RsadeikaRsadeika Posts: 3,565

    So, now I have another little problem, IO between PropGCC and the Python program.

    In my PropGCC program I am using writeFloatPrecision() to send to the Python program on my Rpi. The Python serial program now insists on using decode()/encode() for translating. Unfortunately when I use .decode("utf-8") , it errors with, cannot convert bytes to string or something like that. I thought about using itoa() on the PropGCC side to convert the float to ascii and then use .decode("acsii") on the Python side. But simpletools does not have itoa(). Any suggestions for working this out.

    Thanks
    Ray

  • You could use sprintf to convert a number to an ascii string. However, this will pull in a few Kbytes of code. If you have the space available then that's probably the easiest solution. If you're running out of space you could write your own itoa() function. I've attached itoa10.c, which is some code that I use to generate a decimal ascii string. You could write a routine to generate a hex ascii string, which would take less code.

    c
    c
    623B
  • RsadeikaRsadeika Posts: 3,565

    Thanks Dave.

    This is turning out to be somewhat complicated. I used the itoa10() function and on the Python serial side, when I use the decode() mechanism, it throws an error - "Decode error: 'utf-8' codec can't decode byte 0xf8 in position1: invalid start byte".
    I am using writeStr() to push the value.

    When I don't use the decode(), on the Python serial side, it displays something like 'e0e0e0e0e0e0e0e07'. So it is showing the correct value of 7, but it has all the preceding junk. So, now I wondering if writeStr() is pushing all that stuff, or is it Python serial that is at fault.

    Ray

  • I wonder if you have the baud rate set right. If you are receiving multiple characters on the Python side you may have the baud rate set too high. If I were you I would try running a simple program on the P1 that would just echo the characters received from the Python program.

Sign In or Register to comment.