serial object...so close to working patch

n871's icon

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.

Source Audio's icon

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 ?

n871's icon

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);
}

n871's icon

and the patch

Max Patch
Copy patch and select New From Clipboard in Max.

Source Audio's icon

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

n871's icon

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.

Source Audio's icon

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.

n871's icon

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...

Source Audio's icon

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 ?

n871's icon

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

Source Audio's icon

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

Source Audio's icon

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

Source Audio's icon

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

Source Audio's icon

Pasting into reply field did break comment line at few places, please correct that
when You copy the code

n871's icon

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 : )

Source Audio's icon

Here is zipped version of above examples

n871's icon

...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? : )

Source Audio's icon

Hmm my zipped file seems not to get sent.
Route should come after fromsymbol in Your Patch.

n871's icon

and a third question : ) is it possible you forgot to attach the zipped version in your last reply?

n871's icon

you can send them to *edited*

Source Audio's icon

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.

Source Audio's icon

allready sent

n871's icon

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);
}
}

n871's icon

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);
}
}

Source Audio's icon

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);

Source Audio's icon

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);
}
}

n871's icon

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

n871's icon

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?

Source Audio's icon

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.