Shop OBEX P1 Docs P2 Docs Learn Events
I Need More SimpleIDE Knowledge!!!! — Parallax Forums

I Need More SimpleIDE Knowledge!!!!

NWCCTVNWCCTV Posts: 3,629
edited 2014-09-06 22:05 in Learn with BlocklyProp
I would like to expand my knowledge of SimpleIDE without having to spend hours studying. I want to program my Wild Thumper similar to the Boe Bot Roaming with Ping. I have code for controlling the WT with a remote, but I want to make it autonomous using Ping and IR sensors for now. What I really need to know is can I create "Goto" sections such as in PBasic or what? Will the Activity Bot Tutorials work if I am not using encoders?

EDIT: I think I can figure out how to use the Activity Bot code for Ping to get my WT going somewhat autonomously. I just need to know if I have to use 500 and below for my numbers using abdrive.h in the same way I had to with servo.h. and in Spin.

EDIT 2: I see now that it will not work using abdrive.h. So, I am going to play with the current code using servo.h and see what I can derive from it all.

Comments

  • edited 2014-09-06 08:21
    If you're looking for something a little more like the abdrive library in the ActivityBot tutorials, there's servodiffdrive. Here is an attempt at porting some of your code to this style. I may have botched the turns; feel free to adjust them. Once you get the hang of this, you could try porting the roaming with ping tutorial. It's mainly drive_speeds instead of drive_speed.
    /*
      Blank Simple Project.c
      http://learn.parallax.com/propeller-c-tutorials 
    */
    #include "simpletools.h"                      // Include simple tools
    #include "sirc.h"
    #include "servo.h"
    #include "servodiffdrive.h"
    
    int main()                                    // main function{
    {
      sirc_setTimeout(200);                       // -1 if no remote code in 0.2 s
      while(1)                                    // Repeat indefinitely
      { 
        print("%c remote button = %d%c",          // Display button # decoded
        HOME, sirc_button(2), CLREOL);            // from signal on P10
    
        int button = sirc_button(2);              // Check P10 for remote message
        
        drive_pins(0, 1);
    
        if(button == 16)
        {
          drive_speeds(300, 300); 
        }
        else if(button == 17)
        {
          drive_speeds(-300, -300); 
        }
        else if(button == 18)
        {
          drive_speeds(300, 75); 
        } 
        else if(button == 19)
        {
          drive_speeds(75, 300); 
        } 
        else
        {
          drive_speeds(0, 0); 
        }
      }
    }
    
  • edited 2014-09-06 08:36
    The thing about programming is if you practice a little bit every day or two, treating it like exercise, you get stronger and are able to do more things. For example, try doing one or two pages in the programming basics tutorials http://learn.parallax.com/propeller-c-start-simple today, and then one or two more tomorrow. The most important thing is to arrange your tutorial web page next to the SimpleIDE so you can hand-type the code examples. I have found that that's the most useful thing for really getting the concepts and techniques to sink in: hand entering the code into the IDE even if it's already there as a pre-written file. After you make it through the Start Simple tutorial, make sure to continue with Simple Circuits, Simple Devices (the ones you have at least), and just keep going. Although there are some suggested experiments to do with the examples, it's also good to try something that occurs to you as you go. Even if you went through them once a while back, If you do them again hand entering the code and experimenting, and you'll notice improved programming abilities as you go.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-06 09:42
    The code looks better. I will give it a try later today. Is 300 max speed or is that still 500? and yes, I started on the code samples last night. I use 2 monitors so it makes it easier to code that way. Where I am getting confused is how to use/code more than one sensor in the same program.
  • edited 2014-09-06 10:05
    It's still +/- 500, I just noticed you were using 300 in some Spin code, so I assumed you would want 300 for some reason.

    Good question, I should probably add a tutorial about that. Really good question.

    The general approach is to read your sensors in a loop, and then start with an if statement that deals with the most important sensor. Then the else if can deal with the second most important sensor, and so on. The thing about the code below that is important is if the robot needs to take an evasive maneuver because it detects an object with if(distance < 20), it ignores the remote code in (else if). But, if it there's nothing too close, and you are holding a button, it'll go into the remote control code.


    P.S. Two monitors is great for that. Even 20 minutes every couple days, and you'll notice improvements.
    // THIS IS NOT A COMPLETE PROGRAM
    
    int pingPin = 13, irPin = 2;
    int distance, remoteCode;
    
    while(1)
    {
      distance = ping_cm(pingPin);
      remoteCode = sirc_button(irPin);
      if(distance < 20)
      {
        // Evasive maneuver code
      }
      else if(remoteCode != -1)
      {
        if(remoteCode == 16)
        {
          // Code that does what you want when pressing 16
        }
        else if(remoteCode == 17)
        {
          // Code that does what you want when pressing 17
        }
        ///...etc
      }
    }
    
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-06 10:30
    OK. So if I want the Ping code to override the IR code then I would put the IR code first?
  • edited 2014-09-06 10:45
    It doesn't matter which sensor you check first if all you're doing is putting them in variables like the example in post #5. It's the decision making process that can give one or the other measurement precedence.

    The example in post #5 gives the distance measurement priority with if(distance < 20). If the distance is less than 20, it takes evasive maneuvers and doesn't pay any attention to the IR navigation decisions in the else if part. On the other hand, if the distance is greater than 20, it will continue to the else if. Since it's else if(remoteCode != -1), you have to be pressing a button for any of the nested if...else if... code to get executed. If you're not pressing a button, the loop repeats. If you are pressing a button, it goes into the code that checks which button and takes maneuvering action based on that.

    This provides an example of the difference between if...else if... and just having a bunch of if... statements. If...else if... exits the entire sequence after it has found and responded to a true condition. In contrast, a bunch of if statements all get checked, and whatever is true gets executed.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-06 14:51
    OK. I think I understand what you are saying. So my next hurdle is how to do a Stop, backup and then go forward/left or right when the Ping hits an obstacle. I tried Servo_Stop but that stops the servos and they do nothing else.
  • edited 2014-09-06 15:30
    Servo stop causes problems; avoid it. Please try drvie_speeds(0, 0) instaed.

    Andy
  • edited 2014-09-06 15:33
    Also, you don't need to back up. The try this section in this tutorial shows an effective way to avoid obstacles with Ping)))

    http://learn.parallax.com/activitybot/roaming-ultrasound
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-06 15:43
    OK, I have something totally messed up and I can not seem to get the code in Post 5 in to the code in post 2 to work.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-06 17:11
    I tried the attached code but neither the Remote or Ping works. Also, when pressing a key on the remote, the LED on the Ping lights up. Help!!!!!
    /*Blank Simple Project.c
    http://learn.parallax.com/propeller-c-tutorials 
    */
    #include "simpletools.h" // Include simple tools
    #include "sirc.h"
    #include "servo.h"
    #include "servodiffdrive.h"
    #include "ping.h"
    
    
    int pingPin = 13, irPin = 2;
    int distance, remoteCode;
    int main() // main function{
    {
    
    
    while(1)
    {
    distance = ping_cm(pingPin);
    remoteCode = sirc_button(irPin);
    }
    drive_pins(14, 15);
    if(distance < 20)
    {
    drive_speeds(0,0);
    }
    else if(remoteCode != -1)
    {
    if(remoteCode == 16)
    {
    drive_speeds(300, 300); 
    }
    else if(remoteCode == 17)
    {
    drive_speeds(-300, -300); 
    }
    else if(remoteCode == 18)
    {
    drive_speeds(300, 75); 
    } 
    else if(remoteCode == 19)
    {
    drive_speeds(75, 300); 
    } 
    else
    {
    drive_speeds(0, 0); 
    } 
    }
    }
    
  • edited 2014-09-06 17:20
    Try this.
    #include "simpletools.h"                      // Include libraries
    #include "sirc.h"
    #include "servo.h"
    #include "servodiffdrive.h"
    #include "ping.h"
    
    int pingPin = 13, irPin = 2;                  // Variables
    int distance, button, turn;
    
    int main()                                    // main function
    {
      drive_pins(0, 1);
      sirc_setTimeout(200);                       // -1 if no remote code in 0.2 s
    
      while(1)                                    // Repeat indefinitely
      { 
        distance = ping_cm(pingPin);              // Get distance
        button = sirc_button(irPin);              // Get button
        
        print("%c button = %d, distance = %d%c",  // Display button # decoded
        HOME, button, distance, CLREOL);          // from signal on P2
     
        if(distance < 20)                         // If object too close
        {
          // Evasive maneuver code
          turn = rand() % 2;                      // Random val, odd = 1, even = 0
          if(turn == 1) drive_speeds(-300, 300);  // Start turning
          else          drive_speeds(300, -300);
          while(ping_cm(pingPin) < 20);           // While distance < 20
        }      
        else if(button != -1)                     // Distance > 20, button not -1?
        {
          if(button == 16)                        // Nav based on remote buttons
          {
            drive_speeds(300, 300);               // Forward
          }
          else if(button == 17)
          {
            drive_speeds(-300, -300);             // Backward
          }
          else if(button == 18)
          {
            drive_speeds(300, -300);              // Rotate right
          } 
          else if(button == 19)
          {
            drive_speeds(-300, 300);              // Rotate left
          } 
          else
          {
            drive_speeds(0, 0);                   // Stop
          }
        }      
      }
    }
    
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-06 17:28
    Now that's what I have been trying to do!!!! I am going to print your code and my code out and sit down to study them and figure out what all I was doing wrong. Thanks for all the help with this. I am sure I will be asking more questions but this should do it for now.
  • jazzedjazzed Posts: 11,803
    edited 2014-09-06 17:57
    NWCCTV wrote: »
    Now that's what I have been trying to do!!!! I am going to print your code and my code out and sit down to study them and figure out what all I was doing wrong.


    I seriously recommend using indentation like Andy did to keep your code readable.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-06 18:12
    Andy, I noticed that when using the servodiffdrive.h that the numeric commands are different in that forward is the same number for both motor sides so I do not have to use a positive and negative number. Quite unique!!!
  • edited 2014-09-06 21:51
    To retain the indentation, I copy/paste from SimpleIDE into Windows Notepad, then from Windows Notepad into the forum post.
  • jazzedjazzed Posts: 11,803
    edited 2014-09-06 22:05
    Andy, I always just copy from SimpleIDE and paste into the forum post between the code tags.

    The only problem I have with that is the forums penchant for adding two newlines for every blank newline.
  • edited 2014-09-06 22:05
    Yeah, it seemed like it would be easiest for folks using drive_speeds to have positive values for forward, negative values for backward. Note also that the left wheel is the left parameter and the right wheel is the right parameter. The library does the grunt work of swapping the sign of the right wheel. In contrast, the servo library has positive values for counterclockwise and negative values for clockwise, so the value going to the right wheel has to be negative when going forward, and positive for backward.

    There's a lot more grunt work happening under the hood. One example is that the servo_set call (all roads lead to servo_set) always checks to see if a cog has been launched for servos already. If it has not, the servo_set function does that first. The next time servo_set gets called, it checks, but finds out that the cog has already been started, so it just updates the values the cog needs to make the servo do what servo_set wants. There is also additional work behind the scenes so that your code can say servo_set(14, 2000), servo_set(15, 1000), which is what happens when you call drive_speeds(500, 500) -assuming drive_pins(14, 15). When servo_set sees that second call with pin = 15 instead of pin = 14, if figures out that it's a different pin from last time and sets up a memory slot for the information the cog will need to send control signals to that second servo.
Sign In or Register to comment.