PWM-problem [Motor control interface with Processing + Standard Firmata]

Hello Community,

at the moment I am working on a motor control Interface with Processing 2.x and Standard Firmata for testing purposes in a project in my apprenticeship as electronic technician for automation Technology. We have to construct a (machine) tool from scratch and have to build it.

It´s working pretty fine already but I noticed one problem and poorly can´t find the error source.

I use a Arduino UNO for development but in the tool i will use the MEGA 2560 since I need a lot more I/O´s.

The error is:

PWM on Pin 10 isn´t working as it should. It does nothing unless the PWM value is = 255 where it turns to HIGH from LOW as it should but below 255 it stays LOW.
(maybe the Firmata-library uses the timer that controls pin 10? Do I have a mistake in my Code?)

I hope that somebody can help me

Best regards,
Eatex

Processing-Code: (sorry for no comments at the Moment, if you have some questions just ask)

import processing.serial.*;
import cc.arduino.*;
import controlP5.*;
ControlP5 controlP5;
Arduino arduino;

int Motor_Speed;

boolean direction;

boolean state_brake;

int servoAngle = 90;

int[] pinPWM = {
  3, 11, 10, 0, 0
};
int[] pinBrake = {
  9, 8, 0, 0, 0
};
int[] pinDirection = {
  12, 13, 0, 0, 0
};

int Motor_speed_M1 = 0; // you can change to set a starting value
int Motor_speed_M2 = 0;
int Motor_speed_M3 = 0;
int Motor_speed_M4 = 0;
int Motor_speed_M5 = 0;

boolean direction_M1 = true; // 0: backward, 1: forward
boolean direction_M2 = true;
boolean direction_M3 = true;
boolean direction_M4 = true;
boolean direction_M5 = true;

boolean state_brake_M1 = false; 
boolean state_brake_M2 = false;
boolean state_brake_M3 = false;
boolean state_brake_M4 = false;
boolean state_brake_M5 = false;

int[] y_value_slider = {
  10, 90, 170, 250, 330, 410
};

int[] y_value_radio = {
  60, 140, 220, 300, 380
};


void setup() {
  size(400, 600);
  println(Arduino.list());
  arduino = new Arduino(this, Arduino.list()[1], 57600);
  for ( int i = 0; i <= 13; i++ ) {
    if ( i == 10 ) arduino.pinMode( i, Arduino.PWM );
    else if ( i == 6 ) arduino.pinMode( i, Arduino.SERVO );
    else arduino.pinMode( i, Arduino.OUTPUT );
  }
  controlP5 = new ControlP5(this);
  for (int Mnum=0; Mnum<5; Mnum++) {
    controlP5.addToggle("direction_M"+(Mnum+1), true, 20, y_value_radio[Mnum]-10, 10, 10);
    controlP5.addToggle("state_brake_M"+(Mnum+1), false, 200, y_value_radio[Mnum]-10, 10, 10);
    controlP5.addSlider("Motor_speed_M"+(Mnum+1), 0, 255, 0, 20, y_value_slider[Mnum], 255, 20);
  }
  controlP5.addSlider("servoAngle", 30, 150, servoAngle, 20, y_value_slider[5], 180, 20);
}


void draw() {
  arduino.servoWrite(6, servoAngle);

  for (int Snum = 0; Snum <5; Snum++) {

    if (Snum==0) { 
      Motor_Speed = Motor_speed_M1; 
      state_brake = state_brake_M1; 
      direction = direction_M1;
    }
    if (Snum==1) { 
      Motor_Speed = Motor_speed_M2; 
      state_brake = state_brake_M2; 
      direction = direction_M2;
    }
    if (Snum==2) { 
      Motor_Speed = Motor_speed_M3; 
      state_brake = state_brake_M3; 
      direction = direction_M3;
    }
    if (Snum==3) { 
      Motor_Speed = Motor_speed_M4; 
      state_brake = state_brake_M4; 
      direction = direction_M4;
    }
    if (Snum==4) { 
      Motor_Speed = Motor_speed_M5; 
      state_brake = state_brake_M5; 
      direction = direction_M5;
    }
    arduino.analogWrite(pinPWM[Snum], Motor_Speed);
    if (state_brake) {
      arduino.digitalWrite(pinBrake[Snum], 1);
    } else arduino.digitalWrite(pinBrake[Snum], 0);
    if (direction) { 
      arduino.digitalWrite(pinDirection[Snum], 1);
    } else {
      arduino.digitalWrite(pinDirection[Snum], 0);
    }
  }
}
  for ( int i = 0; i <= 13; i++ ) {
    if ( i == 10 ) arduino.pinMode( i, Arduino.PWM );
    else if ( i == 6 ) arduino.pinMode( i, Arduino.SERVO );
    else arduino.pinMode( i, Arduino.OUTPUT );
  }

Pins 0 and 1 are the hardware serial pins. Hardware serial is how processing and the Arduino communicate. Stop f**king with them.

It’s stupid to have a for loop that does something different each iteration.

    arduino.analogWrite(pinPWM[Snum], Motor_Speed);

Its stupid to be trying to PWM pin 0.

Or to be trying to do anything else to pin 0.

There are only 3 valid values in your pin number arrays, so quit (uselessly) looping 5 times.

PaulS:

  for ( int i = 0; i <= 13; i++ ) {

if ( i == 10 ) arduino.pinMode( i, Arduino.PWM );
   else if ( i == 6 ) arduino.pinMode( i, Arduino.SERVO );
   else arduino.pinMode( i, Arduino.OUTPUT );
 }



Pins 0 and 1 are the hardware serial pins. Hardware serial is how processing and the Arduino communicate. Stop f**king with them.

It's stupid to have a for loop that does something different each iteration.



arduino.analogWrite(pinPWM[Snum], Motor_Speed);



Its stupid to be trying to PWM pin 0.

Or to be trying to do anything else to pin 0.

There are only 3 valid values in your pin number arrays, so quit (uselessly) looping 5 times.

Thank you for your advise, PaulS! :slight_smile:
I´ve corrected those programming mistakes but i couldn´t find a solution for:

It’s stupid to have a for loop that does something different each iteration.

How would you do it in this situation? The ControlP5-Library can´t work with Arrays so I have to save the values as a single variable and execute them in a for-loop. At least with my current programming skills I didn´´t found a better solution. Can you show me a better solution to improve my skills in the future, please?

for (int Snum = 0; Snum <3; Snum++) {

    if (Snum==0) { 
      Motor_Speed = Motor_speed_M1; 
      state_brake = state_brake_M1; 
      direction = direction_M1;
    }
    if (Snum==1) { 
      Motor_Speed = Motor_speed_M2; 
      state_brake = state_brake_M2; 
      direction = direction_M2;
    }
    if (Snum==2) { 
      Motor_Speed = Motor_speed_M3; 
      state_brake = state_brake_M3; 
      direction = direction_M3;
    }
    if (Snum==3) { 
      Motor_Speed = Motor_speed_M4; 
      state_brake = state_brake_M4; 
      direction = direction_M4;
    }
    if (Snum==4) { 
      Motor_Speed = Motor_speed_M5; 
      state_brake = state_brake_M5; 
      direction = direction_M5;
    }
    arduino.analogWrite(pinPWM[Snum], Motor_Speed);
    if (state_brake) {
      arduino.digitalWrite(pinBrake[Snum], 1);
    } else arduino.digitalWrite(pinBrake[Snum], 0);
    if (direction) { 
      arduino.digitalWrite(pinDirection[Snum], 1);
    } else {
      arduino.digitalWrite(pinDirection[Snum], 0);
    }
  }

unfortunately, the problem I have is still not solved.

Pin 10 still just changes to HIGH when PWM value is >=255, below it stays LOW.

Greetings,
EATEX

How would you do it in this situation?

If I asked you to go to the grocery store, stop by the train station, buy gas, see a movie, and pet a dog, would you try to use a for loop to do that? Of course not. None of the things to do are related.

You don’t need a for loop, either.

PaulS:
If I asked you to go to the grocery store, stop by the train station, buy gas, see a movie, and pet a dog, would you try to use a for loop to do that? Of course not. None of the things to do are related.

You don't need a for loop, either.

That is quite true, PaulS.
If I have understood correctly , you would say that this is the better solution?:

arduino.analogWrite(pinPWM[0], Motor_speed_M1);
if (state_brake_M1) {
  arduino.digitalWrite(pinBrake[0], 1);
} else arduino.digitalWrite(pinBrake[0], 0);
if (direction_M1) { 
  arduino.digitalWrite(pinDirection[0], 1);
} else arduino.digitalWrite(pinDirection[0], 0);

arduino.analogWrite(pinPWM[1], Motor_speed_M2);
if (state_brake_M2) {
  arduino.digitalWrite(pinBrake[1], 1);
} else arduino.digitalWrite(pinBrake[1], 0);
if (direction_M2) { 
  arduino.digitalWrite(pinDirection[1], 1);
} else arduino.digitalWrite(pinDirection[1], 0);

arduino.analogWrite(pinPWM[2], Motor_speed_M3);
if (state_brake_M3) {
  arduino.digitalWrite(pinBrake[2], 1);
} else arduino.digitalWrite(pinBrake[2], 0);
if (direction_M3) { 
  arduino.digitalWrite(pinDirection[2], 1);
} else arduino.digitalWrite(pinDirection[2], 0);

If I have understood correctly , you would say that this is the better solution?

Yes.

Thank you Paul!! :slight_smile:
I think that I´m thinking too complicated often and therefore overlook the simplest solution :confused:

But I still got this Problem with the PWM on Pin 10 :frowning:
I´ve tried every pinMode that the Standard-Firmata-Library offers. I´ve tried digitalWrite(), servoWrite() and analogWrite()...but it´s always the same result, Pin 10 just works LOW or HIGH and does not send PWM-Signals as it should actually.
This is confusing me. It´s also no Hardware issue, I´ve already tested it via a Arduino Programm and there it works properly...
Nobody knows a solution for this?

I found the Problem :slight_smile:

I didn´t know that the Servo.h library disables the analogWrite()-function on Pin 9 and 10 at boards other than the Mega but also didn´t expect that this library is the troublemaker ^^

Thank you guys!

Greetings,
EATEX

Fine, now I´m using my MEGA2560R3 and it works :slight_smile:

But now, after I included a Timer Interrupt with Timer5 to check my sensor states every x-millis, I got the same issue with Pin 11 as i had with Pin 10 at the Uno...It´s not a big Problem because i have enough alternative PWM Pins on the MEGA but I ask me from where this issue comes now. As far as I know, Timer 5 has nothing to do with Pin 11.

Can somebody explain me this issue, please?

Greetings,
EATEX