1

Context of the code:

I am trying to control 2 DC motors through an H-gate, this means there are 4 inputs in total: For DC motor 1: Input 1 (VCC) and Input 2 (GND). For DC motor 2: Input 3(VCC) and Input 2 (GND).

Summary of the code:

The global variables are motinpN which are the pins connected to the different inputs.

An array, which is where the different PWM for the motor speeds are stored.

Char x, which is the variable used for the boolean logic.

Then comes the actual loop which consists of 4 similar functions, the "input selector" function and then the statements that turn the integers stored in the inpSpeedS[] arrays into motor speeds.

The issue:

The code won't enter the first loop, i.e it won't advance past

Serial.println("X equals:"); Serial.print(x);"

I would like to know then, what I am doing wrong in order for this not to work?

   int Speed = 0;
const int motinp1 = 2;
const int motinp2 = 3;
const int motinp3 = 4;
const int motinp4 = 5;

char  x = '0';

int inpSpeedS[4]; // An array to determine the speed of each individual input

void setup()
{
  Serial.begin(9600);
  pinMode(motinp1, OUTPUT);
}

void loop() {
  Serial.println("X equals:");
  Serial.print(x);

  if (Serial.available () && (x == '0')) {
    Serial.print("Which input?");
    x = Serial.read();
    Serial.println(x);
  }
  if (Serial.available () && (x == 'a'))
  {
    Serial.println("Input 1 selected");
    inpSpeedS[0] = Serial.parseInt();
    Serial.print("Input 1: ");
    Serial.println(inpSpeedS[0]);
   x = '0'; //reset x, goes back to input selection
  } if (Serial.available () && (x == 'b'))
  {
    Serial.println("Input 2 selected");
    inpSpeedS[1] = Serial.parseInt();
    Serial.print("Input 2: ");
    Serial.println(inpSpeedS[1]);
   x = '0';
  }
  if (Serial.available () && (x == 'c'))
  {
    Serial.println("Input 3 selected");
    inpSpeedS[2] = Serial.parseInt();
    Serial.println("Input 3: ");
    Serial.print(inpSpeedS[2]);
   x = '0';
  }
  if (Serial.available () && (x == 'd'))
  {
    Serial.println("Input 4 selected");
    inpSpeedS[3] = Serial.parseInt();
    Serial.print("Input 4: ");
    Serial.println(inpSpeedS[3]);
   x = '0';
  }
  analogWrite(motinp1, inpSpeedS[0]);
  analogWrite(motinp2, inpSpeedS[1]);
  analogWrite(motinp3, inpSpeedS[2]);
  analogWrite(motinp4, inpSpeedS[3]);
} 

EDIT - I have turned the char 0 from a string literal null to an ASCII code for 0, and same for the other chars. It is still stuck outside of the function loops.

6
  • How it's possible that char x = "0"; doesn't yeld on you that you are assigning pointer to C string into char variable?
    – KIIV
    Commented Jun 13, 2020 at 15:14
  • @KIIV I haven't read any books on C yet, only done Udemy courses, so I unfortunately do not know what you're talking about, other than the most superficial I can google myself to in 10 minutes. Could you please elaborate? Commented Jun 13, 2020 at 15:23
  • 1
    There is a huge difference between '0' and "0". First one is ASCII value of character zero, second one is pointer to memory, where the string containing {'0', '\0'} is stored
    – KIIV
    Commented Jun 13, 2020 at 15:34
  • 1
    Also note you have a shadow x variable in loop. Probably not a good idea.
    – Delta_G
    Commented Jun 13, 2020 at 17:10
  • 1
    Or just lose the "int" in front of x='0';
    – Delta_G
    Commented Jun 13, 2020 at 17:55

1 Answer 1

1

It's screaming on you:

sketch_jun13a.ino:7:11: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

 char  x = "0";

           ^~~

sketch_jun13a.ino: In function 'void loop()':

sketch_jun13a.ino:21:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

   if (Serial.available () && (x == "0")) {

                                    ^~~

sketch_jun13a.ino:21:36: warning: ISO C++ forbids comparison between pointer and integer [-fpermissive]

sketch_jun13a.ino:26:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

   if (Serial.available () && (x == "a"))

                                    ^~~

sketch_jun13a.ino:33:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

     x = "0"; //reset x, goes back to input selection

         ^~~

sketch_jun13a.ino:34:38: warning: comparison with string literal results in unspecified behavior [-Waddress]

   } if (Serial.available () && (x == "b"))

                                      ^~~


sketch_jun13a.ino:41:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

     x = "0";

         ^~~

sketch_jun13a.ino:43:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

   if (Serial.available () && (x == "c"))

                                    ^~~

sketch_jun13a.ino:50:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

     x = "0";

         ^~~

sketch_jun13a.ino:52:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

   if (Serial.available () && (x == "d"))

                                    ^~~

sketch_jun13a.ino:52:36: warning: ISO C++ forbids comparison between pointer and integer [-fpermissive]

sketch_jun13a.ino:58:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

     x = "0";

         ^~~

Basically this is char variable with assigned character literal: char x = '0';

And this is C string: char str[] = "0"; or its equivalent: char str[] = {'0', '\0'};. Where '\0' is so called NUL Terminal character.

Everything about C strings you need to know

EDIT:

Simple demo for the "parser" - it's not perfect but should be enough:

char  x = '0';

int inpSpeedS[4]; // An array to determine the speed of each individual input

void setup() {
  Serial.begin(9600);
  Serial.println("Select channel [a..d] and speed [0..255]: ");
}

void loop() {

  if (Serial.available() > 1) { // wait for more characters in buffer
    switch (Serial.read()) {
      case 'a': inpSpeedS[0] = Serial.parseInt(); break;
      case 'b': inpSpeedS[1] = Serial.parseInt(); break;
      case 'c': inpSpeedS[2] = Serial.parseInt(); break;
      case 'd': inpSpeedS[3] = Serial.parseInt(); break;
      default : return; // skip invalid characters like line endings
    }

    Serial.print("Speeds: ");
    for (auto spd : inpSpeedS) {
      Serial.print(' ');
      Serial.print(spd);
    }
    Serial.println();
    Serial.println("Select channel [a..d] and speed [0..255]: ");

    /*
      analogWrite(motinp1, inpSpeedS[0]);
      analogWrite(motinp2, inpSpeedS[1]);
      analogWrite(motinp3, inpSpeedS[2]);
      analogWrite(motinp4, inpSpeedS[3]);
    */

  }
}

And the result:

-> Select channel [a..d] and speed [0..255]:
<- a547
-> Speeds:  547 0 0 0
-> Select channel [a..d] and speed [0..255]:
7
  • Ah thank you, But by this logic, shouldn't turning [code]char x = "0"[/code] into [code]char x = '0'[/code] then fix the loop? If yes, then something else was also wrong with the loop, since it still is stuck at [code] Serial.println("X Equals:"); Serial.print(x);[/code] Commented Jun 13, 2020 at 15:38
  • You have to fix all of it including 'a', 'b', 'c', 'd'. But there might be another mistake, as the code cannot be compiled due to missing variables I was lazy to add up
    – KIIV
    Commented Jun 13, 2020 at 15:42
  • 1
    Btw, it's not stucked, if you send for example a154, it'll set the first channel to 154, but it should be set once, you don't want to send it each loop. The same as you don't want to send output every loop interation
    – KIIV
    Commented Jun 13, 2020 at 15:53
  • 1
    @GeorgeWTrump I've added little bit simplified example but somehow working
    – KIIV
    Commented Jun 13, 2020 at 16:14
  • 1
    Let us continue this discussion in chat.
    – KIIV
    Commented Jun 13, 2020 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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