3
\$\begingroup\$

So I've wired up a little robot with a sound shield and some sensors. I'm trying to write a sketch that will let check the sensors.

What I'd like for it to do is print out a little menu over serial, wait until the user sends a selection, jump to the function that matches their selection, then (once the function is done) jump back and print the menu again. Here's what I've written, but I'm not a that good of a coder, so it doesn't work. Where am I going wrong?

#include <Servo.h>
Servo steering;
Servo throttle;
int pos = 0;
int val = 0;
void setup(){
  Serial.begin(9600);
  throttle.write(90);
  steering.write(90);
  pinMode(A0, INPUT);
  pinMode(7, INPUT);
  char ch = 0;
}
void loop(){
  Serial.println("Menu");
  Serial.println("--------------------");
  Serial.println("1. Motion Readout");
  Serial.println("2. Distance Readout");
  Serial.println("3. SD Directory Listing");
  Serial.println("4. Sound Test");
  Serial.println("5. Car Test");
  Serial.println("--------------------");
  Serial.println("Type the number and press enter");
  while(char ch = 0){
  ch = Serial.read();}
  char ch;
  switch(ch)
  {
    case '1':
    motion();
  }
   ch = 0;
}
//menu over, lets get to work.
void motion(){
  Serial.println("Haha, it works!");
}

I'm pretty sure a While loop is the right thing to do, but I'm probably implementing it wrong. Can anyone shed some light on this?

\$\endgroup\$

migrated from programmers.stackexchange.com Jun 6 '12 at 11:19

This question came from our site for professionals, academics, and students working within the systems development life cycle.

  • 3
    \$\begingroup\$ First, out here in the real world "shield" and "sketch" are normal words that don't make sense as you used them. No, the arduino marketing folks don't get to redefine standard english words and have the rest of us just go along. Second, this is a software issue. Surely there is a blocking call available in the libraries to get the next byte from the UART. \$\endgroup\$ – Olin Lathrop Jun 6 '12 at 11:27
  • 6
    \$\begingroup\$ @OlinLathrop, Lets tag it arduino and accept this is the language they use inside their community, feel free to share that it is not common language anywhere else but it is okay if they choose to use that term. \$\endgroup\$ – Kortuk Jun 6 '12 at 13:27
  • 2
    \$\begingroup\$ @Kortuk: No, I don't go along with that. I realize those are the terms used in the arduino community, but they have specific and different meanings everywhere else. This is a general electronics forum, not a arduino forum. If arduino people come here, they have to be prepared to talk general electronics correctly. I also deeply resent how the arduino people have tried to hijack common english words for their private use. Every effort should be made not to tolerate this in the larger world. At the very least, we can edjucate people that come here using the wrong terms. \$\endgroup\$ – Olin Lathrop Jun 6 '12 at 14:33
  • 6
    \$\begingroup\$ @OlinLathrop, I tried to say this before but I may have failed to communicate. Explaining the further definitions of this word is very useful, especially as the user branch out. The tags are a way to almost create coexisting subsites, if you are talking in questions that have the arduino tag you can expect shield to be used in this way, attempting to force the community to use a different word everywhere will make the questions significantly less useful to the arduino community on the whole. Educate but try to accept that a different term will be used in their questions. \$\endgroup\$ – Kortuk Jun 6 '12 at 14:44
  • 9
    \$\begingroup\$ @OlinLathrop How fortunate that the rest of the world takes care never to repurpose or overload terms. Like current, or code, or wire, or power. \$\endgroup\$ – Nick Johnson Jun 10 '12 at 9:34
-2
\$\begingroup\$

This codes is for the arduino robot car.

#include "SPI.h"
#include "Mirf.h"
#include "nRF24L01.h"
#include "MirfHardwareSpiDriver.h"
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
#include "HMC5883L.h"
#include "Servo.h"
Servo Servo_8;
Servo Servo_9;
Servo Servo_10;
Servo Servo_11;
Servo Servo_12;
Servo Servo_13;
int IN1=23;
int IN2=22;
int IN3=24;
int IN4=25;
int ENA=5                            ;
int ENB=4;
int LED1=11;
int LED2=12;
float k_8;
float k_9;
float k_10;
float k_11;
float k_12;
float k_13;
float speed_9=1500;
float speed_8=1500;
float speed_10=1500;
float speed_11=1500;
float speed_12=1500;
float speed_13=1500;


struct Axis  // Datas from remote control 
{
 uint16_t axis_1;
 uint16_t axis_2;
  uint16_t axis_3;
 uint16_t axis_4;
 uint16_t axis_5;
 uint16_t axis_6;
 uint16_t axis_7;
  uint16_t axis_8;
};
Axis axis_x;

struct Gesture  // Datas send back to remote control 
{
  long Joystick_1_X;
  long Joystick_1_Y;
  long Joystick_2_X;
  long Joystick_2_Y;
  long Joystick_1;
  long Joystick_2;
  uint16_t null_1;
  uint16_t null_2;
};
Gesture data;

void setup()
{
  Wire.begin();
  Serial.begin(115200);
  ///////////////////////////////////////////
  pinMode(IN1,OUTPUT);
  pinMode(IN2,OUTPUT);
  pinMode(IN3,OUTPUT);
  pinMode(IN4,OUTPUT);
  pinMode(ENA,OUTPUT);
  pinMode(ENB,OUTPUT);
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  digitalWrite(IN1,HIGH);
  digitalWrite(IN2,HIGH);
  digitalWrite(IN3,HIGH);
  digitalWrite(IN4,HIGH);
  Servo_8.attach(8);
   Servo_9.attach(9);
  Servo_10.attach(10);
  Servo_11.attach(11);
  Servo_12.attach(12);
  Servo_13.attach(13);

  /* Part of the protection codes.If he robot was turned on with the angle over 45(-45) degrees,the wheels 
   will not spin until the robot is in right position. */

  // 24L01 initialization
  Mirf.cePin = 53;
  Mirf.csnPin = 48;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"serv1");
  Mirf.payload = 1
  //////////////////////////////////////////////
}

void loop() 
{   
   Recive();
   Arm_Control();

}
 //////////////////////////////////////////////////////
void Recive()
{
  if(!Mirf.isSending() && Mirf.dataReady()){  // Read datas from the romote    contYawer
    Mirf.getData((byte *) &axis_x);
    //Serial.print("data="); Serial.print(axis_x);
//Serial.print("axis_1=");
//Serial.println(axis_x.axis_1);
/*Serial.print("  axis_2=");
Serial.print(axis_x.axis_2);
Serial.print("  axis_3=");
Serial.print(axis_x.axis_3);
Serial.print("  axis_4=");
Serial.print(axis_x.axis_4);
Serial.print("  axis_5=");
Serial.print(axis_x.axis_5);
Serial.print("  axis_6=");
Serial.print(axis_x.axis_6);
Serial.print("  axis_7=");
Serial.print(axis_x.axis_7);
Serial.print("  axis_8=");
Serial.println(axis_x.axis_8);*/

Mirf.setTADDR((byte *)"clie1");
Mirf.send((byte *) &data);  // Send datas back to the contYawer


 }
  else
  {
    axis_x.axis_1 = axis_x.axis_2 = 500;
   }
}
 void Arm_Control()
{
  if((axis_x.axis_5==1)&&(axis_x.axis_1 > 550))
 {
   k_10 = -map(axis_x.axis_1, 531, 1023, 0, 500)*0.01;
  }
  else if((axis_x.axis_5==1)&&(axis_x.axis_1 < 450))
  {
    k_10 = -map(axis_x.axis_1, 0, 469, -500, 0)*0.01;
  }
  else{
    k_10 = 0;
  }

  if((axis_x.axis_5==1)&&(axis_x.axis_2 > 550))
  {
    k_8 = -map(axis_x.axis_2, 531, 1023, 0, 500)*0.01;
  }
  else if((axis_x.axis_5==1)&&(axis_x.axis_2 < 450))
  {
    k_8 = -map(axis_x.axis_2, 0, 469, -500, 0)*0.01;
  }
   else{
    k_8 = 0;
  }
    if((axis_x.axis_5==0)&&(axis_x.axis_2 > 550))
  {
    k_9 = -map(axis_x.axis_2, 531, 1023, 0, 500)*0.01;
  }
  else if((axis_x.axis_5==0)&&(axis_x.axis_2 < 450))
  {
    k_9 = -map(axis_x.axis_2, 0, 469, -500, 0)*0.01;
  }
  else{
    k_9 = 0;
  }

  if((axis_x.axis_5==0)&&(axis_x.axis_1 > 550))
  {
    k_12= -map(axis_x.axis_1, 531, 1023, 0, 500)*0.01;
  }
   else if((axis_x.axis_5==0)&&(axis_x.axis_1 < 450))
  {
    k_12= -map(axis_x.axis_1, 0, 469, -500, 0)*0.01;
  }
  else{
    k_12 = 0;
    }
  if((axis_x.axis_6==0)&&(axis_x.axis_4 > 550))
  {
    k_13= -map(axis_x.axis_4, 531, 1023, 0, 500)*0.01;
  }
  else if((axis_x.axis_6==0)&&(axis_x.axis_4 < 450))
  {
    k_13= -map(axis_x.axis_4, 0, 469, -500, 0)*0.01;
  }
  else{
    k_13 = 0;
  }
   if((axis_x.axis_6==1)&&(axis_x.axis_4 > 550))
  {
    k_11= -map(axis_x.axis_4, 531, 1023, 0, 500)*0.001;
  }
  else if((axis_x.axis_6==1)&&(axis_x.axis_4 < 450))
  {
    k_11= -map(axis_x.axis_4, 0, 469, -500, 0)*0.001;
  }
  else{
    k_11 = 0;
  }
  speed_8 = min(2000, max(800, speed_8 += k_8));
  speed_9 = min(1800, max(1000, speed_9 += k_9));
  speed_10 = min(2500, max(500, speed_10 += k_10));
  speed_11 = min(1800, max(1000, speed_11 += k_11));
  speed_12 = min(1800, max(1000, speed_12 += k_12));
  speed_13 = min(1900, max(1200, speed_13 += k_13));

 Serial.print("  speed_8="); Serial.print(speed_8);Serial.print("        speed_9="); Serial.print(speed_9);
 Serial.print("  speed_10="); Serial.print(speed_10);Serial.print("   speed_11="); Serial.print(speed_11);
 Serial.print("  speed_12="); Serial.print(speed_12);Serial.print("     speed_13="); Serial.println(speed_13);

 Servo_9.writeMicroseconds(speed_9);  
 Servo_8.writeMicroseconds(speed_8);
 Servo_10.writeMicroseconds(speed_10);
 Servo_11.writeMicroseconds(speed_11);
 Servo_12.writeMicroseconds(speed_12);
 Servo_13.writeMicroseconds(speed_13);
 }
\$\endgroup\$
3
\$\begingroup\$

if you would hang up your program until there is a serial command:

use this by example

Serial.flush(); //flush all previous received and transmitted data
while(!Serial.available()) ; // hang program until a byte is received notice the ; after the while()
/*continue program ...*/

and maybe you can write a function

void displayMenu(){
...
}

and call that whenever you want

\$\endgroup\$
  • 1
    \$\begingroup\$ upvoted cause it clearly answers the question. Unfortunately the typo in while(ch == 0); was not mentioned. \$\endgroup\$ – josef Sep 14 '14 at 6:03
5
\$\begingroup\$

Here are some suggestions:

  • move declaration of ch above the while loop
  • you used = instead of ==, so while( ch = 0) will loop forever, because ch = 0 will always evaluate to true. It should be while( ch == 0)
  • refactor your menu display into a DisplayMenu() function, just because it's cleaner that way, then call DisplayMenu() from loop().
\$\endgroup\$
  • \$\begingroup\$ Also don't change the value of character you read. Do something like "while(repeat)" and change the value of repeat to false when you want to stop it. Don't forget to initialize "repeat=true" \$\endgroup\$ – Jamiro14 Jun 6 '12 at 13:45
  • \$\begingroup\$ I don't agree with this, since it is perfectly valid and standard practice to evaluate an input character in a while loop. He merely had an equality syntax error and used = instead of ==. But inside of a loop, I would agree with what you said about modifying the value of the input character, since that obviously defeats the whole point of capturing the keyboard input. \$\endgroup\$ – Dave Jun 6 '12 at 14:16
  • \$\begingroup\$ I'm not saying that he shouldn't evaluate an input character in a while loop, just saying that he shouldn't change its value inside the loop. \$\endgroup\$ – Jamiro14 Jun 6 '12 at 14:25
  • \$\begingroup\$ sorry, I thought you were referring to how he changed the value inside of the evaluation. ;) \$\endgroup\$ – Dave Jun 6 '12 at 14:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.