Adding zeros before an int
Hey,
I'm trying to send this kind of date from Max to Arduino over serial port.
https://www.youtube.com/watch?v=hAFv7o5cG2o&t
So I would need to convert numbers 1 to 001, 2 to 002, 10 to 010 and so on.
I found this thread from the forum which was sort of about the same issue, but it didn't solve it.
https://cycling74.com/forums/format-date-number-to-2-digits-01-02-03-09-10-etc
There is the patch so far. There are four different values between 0 and 180, that would need to be formatted from 10 2 40 180 to 010002040180. It works other ways, except it drops the first zeros out.
what is exactly the problem ?
Max will not allow you to use numbers with leading zeros, only as symbol.
But that is not a problem to send to arduino or ?
So, I'm trying to control multiple servos in arduino by sending data from Max. I haven't tried yet, that is it possible to send the data symbols. I think Arduino might think the quotation marks as some symbols as well. I'm very new to arduino and so far I've only succeeded to control one servo from Max. I have an Adafruit's PWM servo driver and I'm trying to add part of this patch to my patch in Arduino IDE.
https://www.youtube.com/watch?v=hAFv7o5cG2o&t
I have understood that the command string.read in Arduino would be one option, but I haven't really found any good examples how would it work in practice.
I am sorry, but I don't have time to watch any youtube videos.
Controlling servos in arduino has been done and it works, there is no mistery about it.
No matter where serial data come from.
You need to set serial communication and decide how to address individual channels
you either allways send 4 values as list ( and forget that leading zeroes)
and collect the 4 values in arduino, then dispatch them to 4 servo outputs.
Or you prepend something like a b c d for each servo
and then in arduino route the value to servo 1 if it was prepended by a.
here is one example how it could look like :
void setup() {
Serial.begin(115200); // set baud depending on speed needed ...
}
void loop() {
if (Serial.available() > 0) {
int SERVO-0 = Serial.parseInt();
int SERVO-1 = Serial.parseInt();
int SERVO-2 = Serial.parseInt();
int SERVO-3 = Serial.parseInt();
if (Serial.read() == '\n') {
pwm.setPWM(0, 0, SERVO-0); pwm.setPWM(1, 0, SERVO-1); pwm.setPWM(2, 0, SERVO-2); pwm.setPWM(3, 0, SERVO-3);
}}}
----------------
This is just part of serial communication.
when list of 4 numbers gets received, the values get sent to
servos 0 1 2 3
in max just send a list with 4 values
like 100 22 33 128
Amazing! Thank you very much! I'll try to include that to my old patch.
As alternative, and in case many units need to be controlled fast,
one would go different path, prepending ID for each channel
or adding "master" control
This is one example using 10 softPWMs to fade leds
It can be easily adapted for other things, and reduced or expanded.
Main goal is to avoid sending full list for all channels if just one or few changed...
So, I've been trying to get your example code implemented to my earlier working patch, but it doesn't work for some reason. Can you spot where did I go wrong?
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN0 155 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX0 557 // This is the 'maximum' pulse length count (out of 4096)
#define SERVOMIN1 175 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX1 520 // This is the 'maximum' pulse length count (out of 4096)
#define SERVOMIN2 155 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX2 557 // This is the 'maximum' pulse length count (out of 4096)
#define SERVOMIN3 155 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX3 557 // This is the 'maximum' pulse length count (out of 4096)
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
int val0;
int val1;
int val2;
int val3;
int pulse0;
int pulse1;
int pulse2;
int pulse3;
int angle0;
int angle1;
int angle2;
int angle3;
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setPWMFreq(SERVO_FREQ); // Analog servos run at ~50 Hz updates
yield();
}
void loop() {
pulse0 = map(angle0, 0, 180, SERVOMIN0, SERVOMAX0);
//Serial.print("Angle0: ");Serial.print(angle0);
//Serial.print(" pulse0: ");Serial.println(pulse0);
pwm.setPWM(0, 0, pulse0);
pulse1 = map(angle1 ,0, 180, SERVOMIN1, SERVOMAX1);
//Serial.print("Angle1: ");Serial.print(angle1);
//Serial.print(" pulse1: ");Serial.println(pulse1);
pwm.setPWM(1, 0, pulse1);
pulse2 = map(angle2 ,0, 180, SERVOMIN2, SERVOMAX2);
//Serial.print("Angle2: ");Serial.print(angle2);
//Serial.print(" pulse2: ");Serial.println(pulse2);
pwm.setPWM(2, 0, pulse2);
pulse3 = map(angle3 ,0, 180, SERVOMIN3, SERVOMAX3);
//Serial.print("Angle3: ");Serial.print(angle3);
//Serial.print(" pulse3: ");Serial.println(pulse3);
pwm.setPWM(3, 0, pulse3);
if (Serial.available() > 0 ) {
val0 = Serial.parseInt();
Serial.println(val0);
val1 = Serial.parseInt();
Serial.println(val1);
val2 = Serial.parseInt();
Serial.println(val2);
val3 = Serial.parseInt();
Serial.println(val3);
if (Serial.read() == '\n') {
angle0 =val0;
angle1 =val1;
angle2 =val2;
angle3 =val3;
}
}
}
This is the earlier working patch that has only one servo.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN 155 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 557 // This is the 'maximum' pulse length count (out of 4096)
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
int val;
int angle;
int pulse;
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setPWMFreq(SERVO_FREQ); // Analog servos run at ~50 Hz updates
yield();
}
void loop() {
angle =val;
pulse = map(angle,0, 180, SERVOMIN, SERVOMAX);
//Serial.print("Angle: ");Serial.print(angle);
//Serial.print(" pulse: ");Serial.println(pulse);
pwm.setPWM(0, 0, pulse);
if (Serial.available()) {
val = Serial.read();
Serial.println(val);
}
}
You need to post max patch as well.
I need to see how you send the list to serial object,
both for single Servo example and for 4 servos.
Try this:
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN0 155
#define SERVOMAX0 557
#define SERVOMIN1 175
#define SERVOMAX1 520
#define SERVOMIN2 155
#define SERVOMAX2 557
#define SERVOMIN3 155
#define SERVOMAX3 557
#define SERVO_FREQ 50
int angle0; int angle1; int angle2; int angle3;
int pulse0; int pulse1; int pulse2; int pulse3;
void setup() {Serial.begin(9600); pwm.begin();
pwm.setPWMFreq(SERVO_FREQ);}
void loop() {
pwm.setPWM(0, 0, pulse0);
pwm.setPWM(1, 0, pulse1);
wm.setPWM(2, 0, pulse2);
wm.setPWM(3, 0, pulse3);
if (Serial.available() > 0 ) {
angle0 = Serial.parseInt();
angle1 = Serial.parseInt();
angle2 = Serial.parseInt();
angle3 = Serial.parseInt();
if (Serial.read() == '\n'){
pulse0 = map(angle0, 0, 180, SERVOMIN0, SERVOMAX0);
pulse1 = map(angle1 ,0, 180, SERVOMIN1, SERVOMAX1);
pulse2 = map(angle2 ,0, 180, SERVOMIN2, SERVOMAX2);
pulse3 = map(angle3 ,0, 180, SERVOMIN3, SERVOMAX3);
} } }
-------------- This is if 4 ints list is sent from Max
You chose 9600 Baud, so set it in max too.
If you want I could send the code with prepended IDs
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN0 155
#define SERVOMAX0 557
#define SERVOMIN1 175
#define SERVOMAX1 520
#define SERVOMIN2 155
#define SERVOMAX2 557
#define SERVOMIN3 155
#define SERVOMAX3 557
#define SERVO_FREQ 50
byte inByte;
int angle0; int angle1; int angle2; int angle3;
int pulse0; int pulse1; int pulse2; int pulse3;
void setup() {Serial.begin(9600); pwm.begin(); pwm.setPWMFreq(SERVO_FREQ);
}
void loop() {
pwm.setPWM(0, 0, pulse0); pwm.setPWM(1, 0, pulse1);
pwm.setPWM(2, 0, pulse2); pwm.setPWM(3, 0, pulse3);
if (Serial.available() > 0 ) {
inByte = Serial.read();
if (inByte == 'A') {angle0 = Serial.parseInt();
pulse0 = map(angle0, 0, 180, SERVOMIN0, SERVOMAX0);}
if (inByte == 'B') {angle1 = Serial.parseInt();
pulse1 = map(angle1 ,0, 180, SERVOMIN1, SERVOMAX1);}
if (inByte == 'C') {angle2 = Serial.parseInt();
pulse2 = map(angle2 ,0, 180, SERVOMIN2, SERVOMAX2);}
if (inByte == 'D') {angle3 = Serial.parseInt();
pulse3 = map(angle3 ,0, 180, SERVOMIN3, SERVOMAX3);}
}}
max patch
Super! Thanks, I'll try them!
Last one that you sent works perfectly! Thank you very much!
You are welcome.
You say that last one works, does that mean that the first one does not ?
Makes me wonder if not , why ...
I only tested the last one. I have to give the first one also a try later.
ok, thanks.
the last one is a better choice for performance I think,
but it is also handy to see how to collect and route incoming list
as first one does.
Hey there, so the first one works as well! If I'm not incorrect, I assume that I can add more "channels" to the arduino patch by just copying the code and changing the letters to E, F, G, H and so on?
Sure, as many as channels on servo board.
just don't forget to multiply angle and pulse as well