Shop OBEX P1 Docs P2 Docs Learn Events
SimpleIDE fdserial.h — Parallax Forums

SimpleIDE fdserial.h

The fdserial_rxChar should wait until until a byte is received?
(https://propsideworkspace.googlecode.com/hg/Learn/Simple Libraries/TextDevices/libfdserial/Documentation fdserial Library.html#details)

With SPIN exist the function "waitstr" with the FullDuplexSerial that works great.

I want to control the cycles, the Propeller only works if receive a "ok" (I´m testing with LabView).

I have here a simple example with RC Time:
#include "simpletools.h"                      // Include simpletools
#include "fdserial.h"                     

fdserial *LabView;


int main()                                    // main function
{
  LabView = fdserial_open(31, 30, 0, 115200);  
  pause(500);

  char c[10];                               // array with 10 elements
  int cont;
  
  while(1)                                    // Endless loop
  {
    high(0);                                  // Set P0 high
    pause(1);                                 // Wait for circuit to charge
    int t = rc_time(0, 1);                    // Measure decay time on P0
    cont=0;
    if (cont<2)
    {
      c[cont] = fdserial_rxChar(LabView);             // this should wait??????
      cont ++;
    }  
 //   if (c[0]=="o")                                       If this line working I don´t have nothing in serial
//                                                               I´m sending a "ok," from Labview
    {
      dprint(LabView,"%d\n", t*50);                     // Send serial decay time
    }     

    pause(50);                               // Wait 1/10th of a second
  }
}

Any sugestion?
Thanks!

Comments

  • Yes, fdserial_rxChar should be a blocking call. It should wait until a character is received.
  • ASAS Posts: 149
    Thanks DavidZemon.
    There are here something that I don´t understand :P
  • I vaguely remember that simpletools automagically opens a non-fdserial, unbuffered serial port on pins 31 and 30 that runs in the main cog. That's probably interfering with your fdserial cog.
  • Okay, I had a look at your code. Simply change "if (cont < 2)" to "while (cont < 2)"
  • ASAS Posts: 149
    edited 2016-02-02 13:03
    I vaguely remember that simpletools automagically opens a non-fdserial, unbuffered serial port on pins 31 and 30 that runs in the main cog. That's probably interfering with your fdserial cog.
    I think this is probably true, because when I send something to the SimpleIDE Terminal I don´t need fdserial.h.
    Thanks!
    DavidZemon wrote: »
    Okay, I had a look at your code. Simply change "if (cont < 2)" to "while (cont < 2)"
    I agree with you the code is wrong with the "if" I need to use a "while" because I want that Propeller do more than one time to fill the array. Thanks!

    But to solve this problem that Propeller don´t wait for the next "rxserial" is necessary to write:
    fdserial_rxFlush(LabView);
    
    before the "while", example:
    #include "simpletools.h"                      // Include simpletools
    #include "fdserial.h"                        
    
    fdserial *LabView;
    
    
    int main()                                    // main function
    {
      LabView = fdserial_open(31, 30, 0, 115200);  
      pause(500);
    
      char c[10];                            
      int index;
      char Char;
      
      while(1)                                    // Endless loop
      {
        high(0);                                  // Set P0 high
        pause(1);                                 // Wait for circuit to charge
        int t = rc_time(0, 1);                    // Measure decay time on P0
        index=0;
    
        fdserial_rxFlush(LabView);   //********** solved ***************
      
        while (index<2)
        {
          c[index] = fdserial_rxChar(LabView);             //
          index ++;
        }  
    //    if (c[0]=="o")                 // This is not working :(
        {
          dprint(LabView,"%d\n", t*50);                     // Send serial decay time
          dprint(LabView,c[0]);
        }     
    
        pause(50);                               // Wait 1/10th of a second
      }
    }
    
    At this moment is solved the control of each cycle.


    Now I have other problem, LabView sending a "ok", but I don´t know why "c[0]" never exist a "o". :P
  • AS wrote: »
    Now I have other problem, LabView sending a "ok", but I don´t know why "c[0]" never exist a "o". :P

    What are you getting instead?

    You might be losing data through your "fdserial_rxFlush(LabView);".


  • DavidZemonDavidZemon Posts: 2,973
    edited 2016-02-02 18:01
    It sounds like you want to receive two characters, 'o' and 'k' from the terminal and then ignore all other data for a period of time, until you're ready to receive the same two characters again. If this is the case, you may be much better off using serial routines that run in the same cog as your main cog. fdserial is a fantastic object - it allows for high-speed comms in an independent cog (meaning you can concentrate on business logic while a separate cog does the communication).... but that's not what you're using it for in this case.

    Your code above could be written as
    #include "simpletools.h"                      // Include simpletools                    
    
    
    int main()                                    // main function
    {
      pause(500);
    
      char c[10];                            
      int index;
      char Char;
      
      while(1)                                    // Endless loop
      {
        high(0);                                  // Set P0 high
        pause(1);                                 // Wait for circuit to charge
        int t = rc_time(0, 1);                    // Measure decay time on P0
        index=0;
    
         while (index<2)
        {
          c[index] = getChar();             //
          index ++;
        }  
    //    if (c[0]=="o")                 // This is not working :(
        {
          printi("%d\n", t*50);                     // Send serial decay time
          printi(c[0]);
        }     
    
        pause(50);                               // Wait 1/10th of a second
      }
    

    What do you think? Are you planning to take advantage of the asynchronous nature of FdSerial later, is that why you started with it?
    I vaguely remember that simpletools automagically opens a non-fdserial, unbuffered serial port on pins 31 and 30 that runs in the main cog. That's probably interfering with your fdserial cog.

    This is a very understandable assumption, but not correct. You do not have to disable the default serial driver. Like any unused variable, GCC will automatically prune it from your program when it sees that it is unused.
  • ASAS Posts: 149
    What are you getting instead?

    You might be losing data through your "fdserial_rxFlush(LabView);".
    Basically with this part,
    ...
        if (c[0]=="o")                 // This is not working :(
        {
          printi("%d\n", t*50);                     // Send serial decay time
          printi(c[0]);
        }  
    ...
    

    I want have sure that I have a "o" in the array c[0] and this is not happening. Without the "if" everything works ok but I want that the "if" works, in other words, if I have a "o" in the array c[o] the response of Propeller should be the same.

  • ASAS Posts: 149
    DavidZemon,

    I start using "fdserial.h" because I thought that I need use it, like in Spin with the "FullDuplexSerialPlus".

    Thanks a lot for your code, I understand that for this example I only need the "simpletools.h". I think so!

    But with the code you post I still can´t use the "if" which guarantees me that I have a "o" in the first position of the array c[0], for some reason this is not working too :(
    (without the "if" everything is working ok, but I want that "if" :P)
    ...
        if (c[0]=="o")                 // This is not working :(
        {
          printi("%d\n", t*50);                     // Send serial decay time
          printi(c[0]);
        }  
    ...
    

    Now the problem is similar but without the "fdserial.h".

    I hope I have made myself clear.

    If you could help me it would be great! :)

    I´m trying to do similar things that I already do with the Spin and I am a beginner with "C" to the Propeller, because I see here a great potential. I really can´t understant why this is not working! :P


  • DavidZemonDavidZemon Posts: 2,973
    edited 2016-02-02 19:22
    Oh! of course :)

    In C/C++ (and Java too), there is a big difference between "o" and 'o'. Double quotes are used for strings whereas single quotes are used for individual characters. Also, printi only accepts strings, not single characters. So two lines of that block need to be changed:
    ...
        if (c[0]=='o')                 
        {
          printi("%d\n", t*50);                     // Send serial decay time
          putChar(c[0]);                             // You could also write this as: printi("%c", c[0]);
        }  
    ...
    

    Also, knowing that you don't need fdserial (aka, a buffered UART implementation), and based on our previous thread with eFFL and PropWare, you may be interested to hear that you can do this with PropWare's libraries too. Here's what it would look like using PropWare's (unbuffered) UART library:
    #include "simpletools.h"                      // Include simpletools
    #include <PropWare/scanner.h>
    
    using namespace PropWare;
    
    int main()                                    // main function
    {
        pause(500);
    
        char c[10];
        int  index;
        char Char;
    
        while (1)                                    // Endless loop
        {
            high(0);                                  // Set P0 high
            pause(1);                                 // Wait for circuit to charge
            int t = rc_time(0, 1);                    // Measure decay time on P0
            index = 0;
    
            while (index < 2) {
                c[index] = pwIn.get_char();             //
                index++;
            }
            if (c[0] == 'o')                 // This is not working :(
            {
                pwOut << t * 50 << '\n';            // Send serial decay time
                pwOut << c[0];
            }
    
            pause(50);                               // Wait 1/10th of a second
        }
    }
    

    I switched out getChar and printi for pwOut and pwIn. Notice the simple use of << instead of printi and putChar.
  • You're receiving all your data and then validating it. In my experience, I've found that it is always better to validate each byte as it comes. So instead of reading two bytes and making sure they are 'o' and 'k', you should read bytes until you get an 'o' (and do something appropriate for every non-'o' you get), and then read the next character and make sure it is a 'k' (and if it isn't a 'k', do something appropriate).
  • ASAS Posts: 149
    edited 2016-02-03 00:19
    State of play.

    1 - The first code with the "fdserial.h" is working great after write 'o' and not "o" in the line
    if (c[0]=='o')
    
    Only one thing is not working, I still can´t send back the 'o' in the line
    dprint(LabView,c[0]);
    
    The code I´m talking about is:
    #include "simpletools.h"                     // Include simpletools
    #include "fdserial.h"                           // Include fdserial
    
    fdserial *LabView;
    
    int main()                                          // main function
    {
      LabView = fdserial_open(31, 30, 0, 115200);  
      pause(500);
    
      char c[10];                             
      int index;
      
      while(1)                                          // Endless loop
      {
        high(0);                                        // Set P0 high
        pause(1);                                      // Wait for circuit to charge
        int t = rc_time(0, 1);                     // Measure decay time on P0
        index=0;
        fdserial_rxFlush(LabView);
        while (index<2)
        {
          c[index] = fdserial_rxChar(LabView);             
          index ++;
        }  
        if (c[0]=='o')                                 // This is working :)
        {
          dprint(LabView,"%d\n", t*50);     // Send serial decay time
          dprint(LabView,c[0]);                  // I still can´t send back c[0]
        }     
    
        pause(50);                               // Wait 1/20th of a second
      }
    }
    

    2 - But like DavidZemon said I don´t need "fdserial.h" for this especific exercise. With the great help of DavidZemon the solution is:
    #include "simpletools.h"           // Include simpletools                    
    
    int main()                                  // main function
    {
      pause(500);
    
      char c[10];                            
      int index;
      char Char;
      
      while(1)                                    // Endless loop
      {
        high(0);                                  // Set P0 high
        pause(1);                                // Wait for circuit to charge
        int t = rc_time(0, 1);               // Measure decay time on P0
        index=0;
         while (index<2)
        {
          c[index] = getChar();             
          index ++;
        }  
        if (c[0]=='o')                           // This is working :)
        {
          printi("%d\n", t*50);              // Send serial decay time
          putchar(c[0]);                   //Here is possible send back the 'o', only a detail, it accumulate the 'o', maybe I need a command to flush the tx????
        }     
    
        pause(50);                               // Wait 1/20th of a second
      }
    }
    

    3 - The third exercise DavidZemon already solve it in the last post, do this with PropWare's libraries. Only one detail, here I can´t send back the c[0].

    Malfunction summary:
    1 - Can´t send back the c[0];
    2 - Send back too many c[0]. Maybe it needs a TxFlush??;
    3 - Can´t send back the c[0];

    The first exercise is not important (for now) solve it. (But any sugestion is welcome)

    The second it would be interesting solve it.

    The third exercise, DavidZemon please help me! :)


    Electrodude, thanks for your sugestion. I had already thought of something like that, because we never know what is in the serial until see it, is something like the Schrödinger's cat. :P

  • ASAS Posts: 149
    I was looking better for the 2nd exercise, it don´t send always c[0], it accumulate and send 8 'oooooooo'!!
    Strange behavior :S
  • This will apply to a lot of different places around the programming world, not just Simple, not just fdserial, PropWare, or even C/C++! This will apply to Java, Python, and a whole host of other languages.
    LEARN the printf format. This page is a fantastic reference in English, but printf is such a popular function, that you can probably find someone that wrote equivalent documentation in your primary language as well.

    Okay, familiar with printf now? No? Go read some more. Go practice it.

    Done now?

    Great, so as you can see, the first argument to printf is a string. So if you wanted to print a single character, like you have with c[o], then you would write printf("%c", c[0]). Simple right? You could expand on that and make it more human-readable (if you care) and write printf("The first character is: %c\n", c[0]).

    Now, printf is so popular that it has been copied over and over and over again. FdSerial uses a similar function called dprint. The only difference between printf and dprint is that you have to add an extra argument: dprint(LabView, "%c", c[0]).
    If you're using the default serial routines, like print or printi, then it's exactly the same as printf: print("%c", c[0]) and printi("%c", c[0]).
    As for PropWare, on top of the option I showed above with the fancy <<, there's another printf mimic: pwOut.printf("%c", c[0]).

    So, printf is great. It's used all over the place, and if you understand how to use it in one place, you'll know how to use it everywhere. The only fortunate thing about printf (and all of the similar functions like pwOut.printf, print, printi, dprint, etc, etc, etc) is that they take a lot of memory. But don't worry about that until it becomes a problem.

    Okay, so that should answer your first problem right? It might also answer your second issue as well... not sure.

    As for #3.... that's just weird. I'll check in on this again in a bit, but I tried that code for myself and it was working well for me.
  • ASAS Posts: 149
    At this moment exercise 1 and 2 work 100%, I will read more about printf format, for sure!

    Thanks a lot
  • ASAS Posts: 149
    edited 2016-02-03 01:53
    Sorry! I don´t understand what happened... The 3rd exercise is working 100%.

    Thanks! this is everything great
  • Yay! Everything works :D
  • ASAS Posts: 149
    David Zemon,

    I need to go back to here because I was testing again these experiences and I detect strange things :P.

    I use always the same LabView program for the 3 experiences.

    To test the bytes received from the LabView I decided change only one line, the idea is, instead of sending back the 'o', sending back the 'k', and the "if" continue looking for the 'o'.
    The LabView is sending 'ok,'

    1 - The first code with the "fdserial.h" is working great, I only changed
    dprint(LabView,"%c",c[1]);
    
    and now I receive which was expected. (see 1st.jpg)

    The code is:
    #include "simpletools.h"                      // Include simpletools
    #include "fdserial.h"                      
    
    fdserial *LabView;
    
    
    int main()                                    // main function
    {
      LabView = fdserial_open(31, 30, 0, 115200);  
      pause(500);
    
      char c[10];                             
      int index;
      
      while(1)                                    // Endless loop
      {
        high(0);                                  // Set P0 high
        pause(1);                                 // Wait for circuit to charge
        int t = rc_time(0, 1);                    // Measure decay time on P0
        index=0;
        fdserial_rxFlush(LabView);
    //    fdserial_txFlush(LabView);     
        while (index<2)
        {
          c[index] = fdserial_rxChar(LabView);            
          index ++;
        }  
        if (c[0]=='o')       
        {
          dprint(LabView,"%d\n", t*50);                     // Send serial decay time
          dprint(LabView,"%c",c[1]);                           //Send the 'k'
        }     
    
        pause(50);                             
      }
    }
    

    2nd experience, it was working fine, until I changed this line
    printi("%c", c[1]);
    
    to receive the "k" (in the LabView). Now LabView is received something not expected. (see 2nd.jpg)

    The code is:
    #include "simpletools.h"                      // Include simpletools                    
    
    
    int main()                                    // main function
    {
      pause(500);
    
      char c[10];                            
      int index;
      
      while(1)                                    // Endless loop
      {
        high(0);                                  // Set P0 high
        pause(1);                                 // Wait for circuit to charge
        int t = rc_time(0, 1);                    // Measure decay time on P0
        index=0;
    
         while (index<2)
        {
          c[index] = getChar();           
          index ++;
        }  
        if (c[0]=='o')                
        {
          printi("%d\n", t*50);                     // Send serial decay time
          printi("%c", c[1]);                           // Not send the 'k' (see 2nd.jpg)
        }     
    
        pause(50);                             
      }
    }
    

    In the 3rd experience using PropWare I was doing a bad procedure because I conected the Propeller to the Raspberry and to the PC, and I turn off the Propeller each time.
    When I write in the Raspberry "make debug" I don´t put the code in the EEPROM, for that I need write "make run"? (I think you already told me that)
    The results obtained were not true.
    So, with the code you send me I have these results (see 3rd_1.jpg). I don´t understand why I receive before the number "o,". Is not o big problem because I say to the LabView to don´t see it. The rest seems to be all right.
    I change your code to send back the "c[1]" and not the "c[0]" I wrote this "pwOut << c[1];", now I have these results (see 3rd_2.jpg). Labview continue receive "o," before the number (not a big problem) but now Propeller is sending a "," and not a "k".

    I hoje you can help me.
    Thanks a lot.

    296 x 332 - 35K
    319 x 332 - 36K
    321 x 337 - 37K
    331 x 340 - 38K
  • ElectrodudeElectrodude Posts: 1,621
    edited 2016-02-05 17:52
    (nevermind)
  • ASAS Posts: 149
    Eletrodude, the first exercise is working 100%, the second I have again some issue with the getchar(), but the rest of the code is exactly the same! If you can help it would be great.
  • ElectrodudeElectrodude Posts: 1,621
    edited 2016-02-05 20:20
    Did you define getchar()? What is the error you got?
  • ASAS Posts: 149
    edited 2016-02-06 01:57
    I´m not sure if I define "getchar()", but I suspect that I have not done it. How I should do it?

    Everything was working ok, Labview receive back the first letter from the string that it is sending, Labview sending "ok," and receive back the "o". But to test it, I changed to the Propeller send the 2nd letter back, the "k", and this is not happening.
    In the last comment I have here with code, the 1st experience with "fdserial.h" is working great, the "1st.jpg" is what I expect, the 2nd experience is with the "getchar()" and the result obtained is the "2nd.jpg", as can be seen Labview not receive back the "k".

    Thanks
  • ElectrodudeElectrodude Posts: 1,621
    edited 2016-02-05 22:49
    Instead of defining it, you'd probably be better off just replacing it with fdserial_rxChar(LabView) or whatever you do to get a character.
  • ASAS Posts: 149
    Ok! Thanks.
    With fdserial is everything working good.
Sign In or Register to comment.