Low Memory Problem, May Cause Stability Problems ---Error Message

I am trying to build a micro servo robot arm and I a getting a Low Memory message.
Please help.
I get the message with the dfrobot Arduino Uno R3 and the Arduino Mega2560

I have attached the program

Micro Servo Robot

Thanks so much, Please email me so I get your message, I’m not good in these forums.

Daniel Hanson
EMAIL REMOVED

MSR-2017_Comments_Added.ino (11 KB)

Don't put your email in plain text on an internet board. Bots will start slamming you with spam. I reported it to the mods. Hopefully one of them will clean it up if they get to it before you do.

Serial.println("Joint0");

Anything like this where you print a constant string and not a variable you can use the F macro.

This:

Serial.println(F("Joint0"));

will save 7 bytes for that one line. I don't see a ton of that in your code but every little bit helps right?

Are you experiencing any problems? The IDE reports memory usage by global and static variables, but it can't tell how deep the call stack is going to get during run-time. It would be possible to write code that uses 99% of the memory by that report and still run well. And it is definitely possible to use 20% by that report and still run out. What is the percentage it gives you?

int joint0[180];// array for servo(s)
int joint1[180];
int joint2[180];
int joint3[180];

Oh wow. That's a lot of memory right there. You might need a bigger arduino if you want to use that many arrays that big. That's 1440 bytes right there. You only get 2K.

Or you could use that and even way more data if you move it to an SD card or something.

Do those arrays have to be of the int (2 byte) data type? What is the largest number that an element of those arrays will be? If the numbers are less than 256 you could make them byte arrays and save 720 bytes.

Thanks for the help.

Sketch uses 8092 bytes (25)% of the program storage space. Maximum is 322256 bytes.
Global variables use 1864 bytes (91)% of dynamic memory, leaving 104 bytes, local variables.
Max is 2048.

I thought I would be ok with the Mega 2560 because it has 8K of sram.

Thanks so much

I thought I would be ok with the Mega 2560 because it has 8K of sram.

Yeah, that would be no problem.

BUT...

Max is 2048.

That's not what you compiled it for. You gotta select the right board.

Danielhhanson:
Sketch uses 8092 bytes (25)% of the program storage space. Maximum is 322256 bytes.

Something very, very wrong there...

Hello

I found another program for the Micro Servo Robot Arm on the site below but when I compile it I get this message

“mode was not declared in this scope”

Here’s the code I cut and pasted in the IDE

Does anyone see the problem, any help would be greatly appreciated.

int PosCount = 0; // to count number of positions increased when button pressed
int PosCountMax = 0; // number of positions recorded when double button push initiates replay mode int PosReached = 0; // used to check that arm has moved from one recorded position to next position void setup() { for(int i = 0; i <100 ; i++ ){ for(int p = 0; p <4 ; p++ ){ ArmPos*[p] = -1; } } pinMode(PinButton1 , OUTPUT); digitalWrite(PinButton1 ,LOW); pinMode(PinButton2, INPUT_PULLUP); // I have made a small change here due to problem using some Arduinos //attachInterrupt( digitalPinToInterrupt(PinButton2),ButtonPress , LOW ); // digitalPinToInterrupt(PinButton2) may not be defined! attachInterrupt( 1,ButtonPress , LOW ); // interupt to capture button presses // attach servos to relervent pins on arduino nano Arm0Servo.attach(12); // grip 90 to 180 open limits of servo movement Arm1Servo.attach(11); // elbow to 130 up Arm2Servo.attach(10); // shoulder 10 to 50 down Arm3Servo.attach(9); // turn 0 to 180 right }*
void loop() { switch(mode){ case 1 : // program robot arm. 1 press to remember position. 2 presses to progress next case 2 replay mode // analogRead(pin) that reads poteniometers on training arm PosArm[0] = map(analogRead(14),480,1024,180,90); // map (480,1024 value from potentiometer to 180,90 value sent to servo) PosArm[1] = map(analogRead(15),180,1000,130,10); PosArm[2] = map(analogRead(16),950,400,80,10); PosArm[3] = map(analogRead(17),0,1024,180,10); MoveArm(); // call method if(buttonPress == 1){ // flag set by interupt when button is pressed buttonPress = 0; // reset flag if( millis() > (lastButtonPressTime + 1000)){ // only one button press in one secound // record position of arm PosArm to array[100] of armpositions ArmPos[PosCount][0] = PosArm[0]; ArmPos[PosCount][1] = PosArm[1]; ArmPos[PosCount][2] = PosArm[2]; ArmPos[PosCount][3] = PosArm[3]; if( PosCount < 100) { // stop recording if over 100 positions recorded (memory limitations) PosCount++; } }else{ // more than one button press mode = 2; // go to next phase PosCountMax = PosCount; // set number of arm positions recorded PosCount = 0; // reset count ready to read arm position array from begining } lastButtonPressTime = millis(); } break; case 2 : // read arm position array PosReached = 0; for(int i = 0; i <4 ; i++ ){ //adjust servo positions // we move the servos in small steps and the delay(20) makes arm motion smooth and slow if( PosArm > ArmPos[PosCount]) PosArm = PosArm - 1; // if actual position is greater than requird position reduce position by 1 if( PosArm < ArmPos[PosCount]) PosArm = PosArm + 1; // if actual position is less than required position value increase position valuue by 1 if( PosArm == ArmPos[PosCount]) PosReached++; // check if servo has reached required position/angle } if(PosReached == 4) PosCount++; // if all 4 servos have reached position then increase array index (PosCount)to next position in array if(PosCount == PosCountMax) PosCount = 0; // if end of array reached reset index to 0 and repeat. MoveArm(); // physically move arm to updated position, this is broken into small steps delay(20); // pause between moves so over all motion is slowed down break; default : break; } }
void MoveArm() { // write arm position data to servos for (int i = 0 ; i < 4 ; i++) { if (PosArm < 5) PosArm = 5; // limit servo movement to prevent hitting end stops if (PosArm > 175) PosArm = 175; // servo.write limited 5 - 175 } Arm0Servo.write(PosArm[0]); Arm1Servo.write(PosArm[1]); Arm2Servo.write(PosArm[2]); Arm3Servo.write(PosArm[3]); } void ButtonPress(){ // interupt to capture button press if(micros() > (bounceTime + 3000)){ // debounce timer bounceTime = micros(); // ingnore interupts due to button bounce buttonPress = 1; // flag for button pressed } }

When you've run the auto-formatted tool on the code, please remember to use code tags when posting code.

Hello I reposted this because I wanted to reflect the correct subject of my programming problem.

I found another program for the Micro Servo Robot Arm on the site below but when I compile it I get this message. Any help would be greatly appreciated.

“mode was not declared in this scope”

Here’s the code I cut and pasted in the IDE

Does anyone see the problem, any help would be greatly appreciated.

int PosCount = 0; // to count number of positions increased when button pressed
int PosCountMax = 0; // number of positions recorded when double button push initiates replay mode int PosReached = 0; // used to check that arm has moved from one recorded position to next position void setup() { for(int i = 0; i <100 ; i++ ){ for(int p = 0; p <4 ; p++ ){ ArmPos[p] = -1; } } pinMode(PinButton1 , OUTPUT); digitalWrite(PinButton1 ,LOW); pinMode(PinButton2, INPUT_PULLUP); // I have made a small change here due to problem using some Arduinos //attachInterrupt( digitalPinToInterrupt(PinButton2),ButtonPress , LOW ); // digitalPinToInterrupt(PinButton2) may not be defined! attachInterrupt( 1,ButtonPress , LOW ); // interupt to capture button presses // attach servos to relervent pins on arduino nano Arm0Servo.attach(12); // grip 90 to 180 open limits of servo movement Arm1Servo.attach(11); // elbow to 130 up Arm2Servo.attach(10); // shoulder 10 to 50 down Arm3Servo.attach(9); // turn 0 to 180 right }
void loop() { switch(mode){ case 1 : // program robot arm. 1 press to remember position. 2 presses to progress next case 2 replay mode // analogRead(pin) that reads poteniometers on training arm PosArm[0] = map(analogRead(14),480,1024,180,90); // map (480,1024 value from potentiometer to 180,90 value sent to servo) PosArm[1] = map(analogRead(15),180,1000,130,10); PosArm[2] = map(analogRead(16),950,400,80,10); PosArm[3] = map(analogRead(17),0,1024,180,10); MoveArm(); // call method if(buttonPress == 1){ // flag set by interupt when button is pressed buttonPress = 0; // reset flag if( millis() > (lastButtonPressTime + 1000)){ // only one button press in one secound // record position of arm PosArm to array[100][] of armpositions ArmPos[PosCount][0] = PosArm[0]; ArmPos[PosCount][1] = PosArm[1]; ArmPos[PosCount][2] = PosArm[2]; ArmPos[PosCount][3] = PosArm[3]; if( PosCount < 100) { // stop recording if over 100 positions recorded (memory limitations) PosCount++; } }else{ // more than one button press mode = 2; // go to next phase PosCountMax = PosCount; // set number of arm positions recorded PosCount = 0; // reset count ready to read arm position array from begining } lastButtonPressTime = millis(); } break; case 2 : // read arm position array PosReached = 0; for(int i = 0; i <4 ; i++ ){ //adjust servo positions // we move the servos in small steps and the delay(20) makes arm motion smooth and slow if( PosArm > ArmPos[PosCount]) PosArm = PosArm - 1; // if actual position is greater than requird position reduce position by 1 if( PosArm < ArmPos[PosCount]) PosArm = PosArm + 1; // if actual position is less than required position value increase position valuue by 1 if( PosArm == ArmPos[PosCount]) PosReached++; // check if servo has reached required position/angle } if(PosReached == 4) PosCount++; // if all 4 servos have reached position then increase array index (PosCount)to next position in array if(PosCount == PosCountMax) PosCount = 0; // if end of array reached reset index to 0 and repeat. MoveArm(); // physically move arm to updated position, this is broken into small steps delay(20); // pause between moves so over all motion is slowed down break; default : break; } }
void MoveArm() { // write arm position data to servos for (int i = 0 ; i < 4 ; i++) { if (PosArm < 5) PosArm = 5; // limit servo movement to prevent hitting end stops if (PosArm > 175) PosArm = 175; // servo.write limited 5 - 175 } Arm0Servo.write(PosArm[0]); Arm1Servo.write(PosArm[1]); Arm2Servo.write(PosArm[2]); Arm3Servo.write(PosArm[3]); } void ButtonPress(){ // interupt to capture button press if(micros() > (bounceTime + 3000)){ // debounce timer bounceTime = micros(); // ingnore interupts due to button bounce buttonPress = 1; // flag for button pressed } }mode

Back to reply #8.
Your code is illegible

I ran the auto formatting tool, but I don't know what use code tags when posting means that was mentioned in reply #8.

I'm just trying to get this code to operate a micro servo robot arm, I'm not a programmer.

Could you give me an example
Thanks so much,

Paste the code into the IDE and add carriage returns to make the code readable.
2 or 3 big long lines is not decipherable.

Thanks so much, I will give it a try.
Merry Christmas!

In

void loop() { switch(mode)

mode is never declared or even used anywhere else.

evanmars:
In

void loop() { switch(mode)

mode is never declared or even used anywhere else.

It is and it isn’t :wink: The source (whoever that is) on the website where this mess came from forgot to use

 tags or forgot to replace CR/LF by
tags. Hence the mess; nearly everything is commented out.

Idiots that don’t proof read.

Pretty sure it isn't. Went through the task of putting it in the IDE and formatting. I may have missed it, but didn't find "mode" anywhere else.

Damn, you're right. Should have sworn that I saw it.