serial object...so close to working patch
Hi,
I'm trying to receive data from my arduinos in Max through the serial object.
But for some reason I always have to start the serial monitor of the arduino software to get everything working.
Does anyone recognize the problem? Thank you.
It is difficult to say what could be wrong without having a look in Arduino code,
but one should not use arduino IDE and Max at the same time.
You are mentioning Arduinos, are You using several Arduinos at the same time ?
my test was done with only one arduino due. The arduino software was not running. But I always need to start it's serial monitor to get things going. The arduino code:
void setup(){
// create serial buffer
Serial.begin(250000);
}
void loop(){
// pot input
int pot1 = analogRead(0);
analogReadResolution(12);
int pot2 = analogRead(3);
analogReadResolution(12);
int pot3 = analogRead(6);
analogReadResolution(12);
int pot4 = analogRead(9);
analogReadResolution(12);
int pot5 = analogRead(11);
analogReadResolution(12);
Serial.print(pot1);
Serial.print(" ");
Serial.print(pot2);
Serial.print(" ");
Serial.print(pot3);
Serial.print(" ");
Serial.print(pot4);
Serial.print(" ");
Serial.println(pot5);
}
and the patch
I see, arduino due has 2 Usb Ports, could it be that they You are connecting/initialising wrong one ?
Or is speed of 250000 not working ?
I have experienced sometimes initialisation problems with serial port
if Serial Port had fixed argument.
Sending it a delayed port message solved the problem in that case
The speed of 250.000 was not working. I lowered it to 76.800 because I somewhere read that 100.000 can already give problems in Max.
I hope this speed is still fine. I just need feedback from potentiometers.
Good that You solved it. 57600 would definitely be good enough for 6 pots, even 9600 would do.
What I would change is to put some sort of thinning in Data stream.
You are sending very fast 6 values form arduino, even if no pot changes.
There are many examples for that in Arduino.
Instead of sending 6 pot values, one could send just the changed pot value.
Prepend a char like A for pot 1, B for pot 2 etc and send them only if pot value changed.
In max route A B C D E F would get the 6 potis out.
Thanks for your reply. the problem however is that all the pots are constantly changing (small changes) even when I don't touch them. So I should program them to send values when the change is bigger than 3 or something. Do I really gain a lot (cpu-wise) when I program things like you suggest? I do use 5 arduinos in a single patch, receiving 20-30 pots...
Depending on grounding, shield etc Sliders do have some Jitter ( jumping up and down).
You definitely have to smooth that, not only because Serial Port might get overloaded,
but also controls could become very unresponsive when You try to send received data
to Audio Objects etc.
Of course, one can insert change object in max after each Pot,
but it is much better to deal with that on arduino side.
If You want I could post a few examples dealing with that.
Do You really need 12 bit resolution ?
I need some pots to be 12 bit, but not all of them. I guess I can change that easily by typing analogReadResolution(10) instead of (12).
Maybe 10 is the default and I don't need to type anything at all. My arduino sketch is on top of this page, if you have ideas to improve it like you say, that would be great. All ideas are very welcome. I also find this page in the meanwhile: http://forum.arduino.cc/index.php?topic=163149.0
byte currentPot[6] = {0,0,0,0,0,0}; byte pot[6] = {0,0,0,0,0,0};
int THRESHOLD = 10; // amount for "Pot Value Changed" recognition, adjust according to Pots jitter and resolution
void setup() { Serial.begin(57600); }
void loop() { analogReadResolution(12);
for(int i=0; i
if(abs(currentPot[i] - pot[i]) > THRESHOLD) // analog pin which value changed more than thresh ammount since last reading
{ Serial.print(i); Serial.print(" "); Serial.println(currentPot[i]); pot[i] = currentPot[i]; delay(10);}}}
// in max use route 0 1 2 3 4 5 to output 6 Pot Values
int Pot1 = 0;int Pot2 = 0;int Pot3 = 0;int Pot4 = 0;int Pot5 = 0;int Pot6 = 0;
int exPot1 = 0;int exPot2 = 0;int exPot3 = 0;int exPot4 = 0;int exPot5 = 0;int exPot6 = 0;
int THRESHOLD = 10; //threshold amount for "Pot Value Changed" recognition, adjust according to Pots jitter and resolution
void setup() {Serial.begin(57600);}
void loop(){analogReadResolution(12);
Pot1 = analogRead(A0);Pot2 = analogRead(A1);Pot3 = analogRead(A2);Pot4 = analogRead(A3);Pot5 = analogRead(A4);Pot6 = analogRead(A5);
if(abs(Pot1 - exPot1) >= THRESHOLD){Serial.print("A "); Serial.println(Pot1); Pot1 = exPot1;}
if(abs(Pot2 - exPot2) >= THRESHOLD){Serial.print("B "); Serial.println(Pot2); Pot2 = exPot2;}
if(abs(Pot3 - exPot3) >= THRESHOLD){Serial.print("C "); Serial.println(Pot3); Pot3 = exPot3;}
if(abs(Pot4 - exPot4) >= THRESHOLD){Serial.print("D "); Serial.println(Pot4); Pot4 = exPot4;}
if(abs(Pot5 - exPot5) >= THRESHOLD){Serial.print("E "); Serial.println(Pot5); Pot5 = exPot5;}
if(abs(Pot6 - exPot6) >= THRESHOLD){Serial.print("F "); Serial.println(Pot6); Pot6 = exPot6;}
delay(10);
}
// This is version with free assignable Analog inputs.
// in Max use route A B C D E F to output 6 Pot values
Have a look at both examples, the first is really efficient, one array reads 6 pots,
monitors if between 2 readings any pot moved more than set Threshold, and sends just that pots value.
The second one does the same, but has free assignable Analog inputs,
Well also the first one could be edited so that pots don't go from A0 - A5 but any other number,
only numbers must be in a row
Pasting into reply field did break comment line at few places, please correct that
when You copy the code
Thank you so much man, I will try this tomorrow as it is already getting quite late here in Belgium. Very curious to see how this works. One question: where do I have to use the route object in Max? Right after the serial object? Or do I have to keep the sel, zl group, itoa and other objects from my original patch ? (also pasted above) As you may have noticed I'm not an arduino expert : )
Here is zipped version of above examples
...and another question if I may: In my original setup I always skipped an analog inputs because I thought they might affect each other otherwise, being located so close together on the board. Does this make sense or am I speaking nonsense? : )
Hmm my zipped file seems not to get sent.
Route should come after fromsymbol in Your Patch.
and a third question : ) is it possible you forgot to attach the zipped version in your last reply?
you can send them to *edited*
Analog inputs which are floating ( unconnected) can influence readout on other analog inputs.
So best is to ground unused ones, or declare them as Digital inputs and use internal pullup
on boards which alow that.
allready sent
Unfortunately it doesn't seem to be working. I also tried the very simple sketch below. Still the serial monitor is outputting lists like
125
125
125
126
125
....
so the sketch compiles and uploads without a problem, but the calculation isn't being made...
I'm using an arduino due, maybe this has something to do with it...
int potPin = 0;
int old_poten;
void setup() {
Serial.begin(9600);
}
void loop() {
int poten = map(analogRead(potPin), 0, 1023, 0, 255);
if(abs(potPin - old_poten) > 5)
{
// Send potPin
old_poten = potPin;
Serial.println(poten); // send it out
delay(10);
}
}
somehow I can't edit my previous post...the button disappeared...this simple patch is working:
int pot;
int expot;
void setup() {
Serial.begin(9600);
}
void loop() {
int pot = analogRead(0);
if(abs(pot - expot) > 10)
{
// Send pot
expot = pot;
Serial.println(pot); // send it out
delay(10);
}
}
I have tested both examples and they work properly.
I only forgot to map 1023 to 255, so only 0 -255 range was sent.
The first code You posted has several mistakes.
But You have realised that allready.
It is important to init the ints at the beginning
int pot1 = 0;
int expot1 = 0;
int pot2 = 0;
int expot2 = 0;
So the pot example i sent using individual Analog Inputs should work fine,
just map the range 0 1023 to 0 255 or simply divide
like int pot1 = analogRead(A0)/4;
or if large numbers 0 1023 have to be sent use print(pot, DEC);
int poten = 0;
int old_poten = 0;
void setup() {
Serial.begin(57600);
}
void loop() {
int poten = analogRead(A0);
if(abs(poten - old_poten) > 5){
Serial.println(poten, DEC);
old_poten = poten;
delay(100);
}
}
I think I finally get it....see part of the serial monitor feedback below. I was confused to see A 505 followed by A 506, because the difference is only 1 (the threshold being 10) . But 505 wasn't actually followed by 506 but with something like 520 right? and 520 was filtered out? Makes sense...
A 505
B 347
C 285
D 268
E 253
F 230
A 506
B 351
C 290
D 249
E 226
F 230
Well, if the above is true, I have one last question. My due has 12 analog inputs. Is it better to use inputs 1, 3, 5, 7, 9, 11 and ground 2, 4, 6, 8, 10 than using 1-6 and grounding 7-12? in other words can CONNECTED analog inputs affect each other, though they shouldn't?
the threshold works on small jitter, wenn pot starts moving it should have full resolution,
not omitting anything.
And You can use all 12 Analog inputs without problem.
There should be no difference if 1-6, or every second one is used etc.
The unconnected ( not wired potis) float and jump all over the place, so You can just ground them,
or do pinmode :
void setup() {
//configure pin as an input and enable the internal pull-up resistor
pinMode(14, INPUT_PULLUP);
Depending on board, analog pins can be used as digital pins, and one can enable
internal pullup.
Pin numbering for analog pins starts after last digital pin, for example Duemilanove
has 13 D Pins, so A0 is pin 14.
This is true for all ATMEGA based arduinos.