Placing values in arrays

Im trying to make a 3 state machine:

  1. Manual control of the servo by a potentiometer
  2. Recording any movement of the potentiometer and placing the value into an array
  3. Repeating the recorded movement from state 2
//SERVO
 #include <Servo.h>
Servo servo1;
int potpin1;
//////////////////////////////////////////////////////
//STATEMACHINE
int SW1=2;
int state=0;
int cnt=0;
/////////////////////////////////////////////////////
//MEMORY
int storage[720];
int Pval1=0;
int val1;
/////////////////////////////////////////////////////
void setup() 
{
 Serial.begin(9600);
 servo1.attach(9); 
 digitalWrite(SW1, HIGH);
}

void loop() 
{
 ///////////////////////////////////////////////////////
 val1 = analogRead(potpin1);          
 val1 = map(val1, 0, 1023, 0, 180);    
 servo1.write(val1);                


if(!digitalRead(SW1))
 {
   delay(50);
   if(!digitalRead(SW1))
     {
       statemachine();
       while(!digitalRead(SW1));
     }
 }
 delay(10);
///////////////////////////////////////////////////////////////
 if(val1!=Pval1)
 {
     Serial.print(val1);
     Serial.print(F(" Deg"));
     Serial.println();   
     Pval1=val1;
     delay(10);
 }
}

////////////////////////////////////////////////////////////////
void statemachine(void)
{
 switch(state)
 {
////////////////////////////////////////////////////////////////
   case 0:
   Serial.println(F("Manual Control"));
   Serial.println();
   state++;
   break;
   
///////////////////////////////////////////////////////////////
   case 1:
     Serial.println(F("Recording"));
   state++;
   break;
   
///////////////////////////////////////////////////////////////    
   case 2:
   Serial.println(F("Autonomous"));
   state=0;
   break;
   
 }
}

Im having trouble with state 2. Any advice would be appreciated.
Thanks in advance

I think you're making incorrect use of a statemachine. Your code will race through the states (except for the delay for the debouncing).

Secondly, if I understand you correctly, you need to fill an array in recording mode. How many values do you want to store?

Secondly, if I understand you correctly, you need to fill an array in recording mode. How many values do you want to store?

That's my understanding too.

How often should the pot value be saved I wonder ?

sterretje:
I think you're making incorrect use of a statemachine. Your code will race through the states (except for the delay for the debouncing).

Secondly, if I understand you correctly, you need to fill an array in recording mode. How many values do you want to store?

In the Serial it doesnt seem to go through the states repeatedly, only displaying the different staes when the digital pin is high. And yes I'd need to fill the array in reccording mode for a maximum of 360 different values. I know this must seem fairly amatuer but I'm very new to coding, sorry.

I'd need to fill the array in reccording mode for a maximum of 360 different values.

Sorry to sound picky, but the Devil is in the detail. What counts as a different value ? How much should a value vary before being regarded as significant ?

Val1 is being stored and can take any value from 0 to 180 as it represents the ange in degrees of the servo, so Id want to store any new angle that is read.

Welcome to the Forum. Please read these two posts:

How to use this forum - please read.
and
Read this before posting a programming question ...
You may also find useful information that would answer your question here:
Useful links - check here for reference posts / tutorials

You have posted code without using code tags. The code tags make the code look like this

//SERVO
  #include <Servo.h>
Servo servo1;
int potpin1;
//////////////////////////////////////////////////////
//STATEMACHINE
int SW1=2;
int state=0;
int cnt=0;
/////////////////////////////////////////////////////
//MEMORY
int storage[720];
int Pval1=0;
int val1;
 /////////////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);
  servo1.attach(9);
  digitalWrite(SW1, HIGH);
}

void loop()
{
  ///////////////////////////////////////////////////////
  val1 = analogRead(potpin1);         
  val1 = map(val1, 0, 1023, 0, 180);   
  servo1.write(val1);               


if(!digitalRead(SW1))
  {
    delay(50);
    if(!digitalRead(SW1))
      {
        statemachine();
        while(!digitalRead(SW1));
      }
  }
  delay(10);
///////////////////////////////////////////////////////////////
  if(val1!=Pval1)
  {
      Serial.print(val1);
      Serial.print(F(" Deg"));
      Serial.println();   
      Pval1=val1;
      delay(10);
  }
}

////////////////////////////////////////////////////////////////
void statemachine(void)
{
  switch(state)
  {
////////////////////////////////////////////////////////////////
    case 0:
    Serial.println(F("Manual Control"));
    Serial.println();
    state++;
    break;
   
///////////////////////////////////////////////////////////////
    case 1:
      Serial.println(F("Recording"));
    state++;
    break;
   
///////////////////////////////////////////////////////////////   
    case 2:
    Serial.println(F("Autonomous"));
    state=0;
    break;
   
  }
}

when posting source code files. It makes it easier to read, and can be copied with a single mouse click. Also, if you don't do it, some of the character sequences in the code can be misinterpred by the forum code as italics or funny emoticons.
If you have already posted without using code tags, open your message and select "modify" from the pull down menu labelled, "More", at the lower left corner of the message. Highlight your code by selecting it (it turns blue), and then click on the "</>" icon at the upper left hand corner. Click on the "Save" button. Code tags can also be inserted manually in the forum text using the code and /code metatags.

Unless the sketch is too large, it's better if you post your code, rather than attach it. When it's attached, we have to download it, create a folder then open your code in our IDE. And afterwards, the folder remains unless we navigate to the "Temp" folder and manually remove it. It's much easier to just view the code in your post.

Many questions can be answered by reading the documentation which is provided with the IDE, available under the help tab, or online here.

What's missing is some kind of "if" around the "state++" to control transition between states.

jaq252:
In the Serial it doesnt seem to go through the states repeatedly, only displaying the different staes when the digital pin is high.

I missed the while at the after your call to statemachine(); you're waiting for the button to be released again. Sorry for that.

if(!digitalRead(SW1))
  {
    delay(50);
    if(!digitalRead(SW1))

Did SW1 change at all between these two tests?

jaq252:
Val1 is being stored and can take any value from 0 to 180 as it represents the ange in degrees of the servo, so Id want to store any new angle that is read.

Sorry, but still more information needed.

  1. How often will the pot values be read to determine whether it has changed ?
  2. If the system is to play back the original input, is it required to play it back at the same rate as the original input ?
  3. What should happen if the pot does not move for 2 or more consecutive readings ? Is it good enough to record the position just once which will result in the playback not being the same as the original input ?
  1. The period of the servo is 1.32s/rev. For the purpose of the servo i wouldnt really need more than 2 half rotations so (1.32/360) so 0.0037s
    2)Yeah it would be preferable for it to play back at the same rate
  2. It stop reccording when the array was filled or state 3 was entered(eg, where the digital pin is high)

The best solution to meet your requirements would be to read the pot, or the calculated servo position, every 0.0037 seconds and to save the value whether or not it had changed since the previous reading. It would be better to use the servo position as its value will fit in a byte thus saving memory. Once saved the values could be played back at the same speed.

However, 360 readings every 0.0037 of a second is only going to take 1.3 seconds or so. Are you sure that you have calculated the recording period correctly ?

How would I go about storing the readings ?

UKHeliBob:
The best solution to meet your requirements would be to read the pot, or the calculated servo position, every 0.0037 seconds and to save the value whether or not it had changed since the previous reading.

In its current state the sketch prints the angle of the servo to the serial whenever it changes. How can i store this to be retreived in state 3. As I said in the OP i would guess it wuld be placed into an array but im not quite sure how and where I would code this. would it be within the case or an if statement in the void loop?

Use the BlinkWithoutDelay principle and use millis() for timing so that the code is not blocked and can run freely.

declare an array of bytes to hold the readings
declare current time, previous recording time and interval as unsigned long variables
declare the array index variable and set it to zero
set previous recording time = millis()
set the interval variable to the number of milliseconds between readings

start of loop()
  current time = millis()
  if current time - previous recording time >= recording interval
    previous recording time = current time  //ready for next check
    read the pot
    calculate the servo position
    move the servo
    
    save servo position to array at the array index position
    increment the array index
    if array index is at max
      stop recording
    end if
  end if
end of loop()

Thanks, but what would the code be for placing the read of the potentiometer into the array?

TheArray[arrayIndexValue] = servoPosition;
arrayIndexValue++;  //ready for next time

Substitute your variable names for my examples.

Thanks

  #include <Servo.h>
Servo servo1;
int potpin1=0;
unsigned long previousMillis = 0;   
int storage[720];
int val1;
const long interval = 10;  

void setup() 
{
  Serial.begin(9600);
  servo1.attach(9); 
  Serial.print();
}

void loop() 
{
  byte i;
  val1 = analogRead(potpin1);          
  val1 = map(val1, 0, 1023, 0, 180);    
  servo1.write(val1);  
 unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval)
  {
      previousMillis = currentMillis;

      for(i=0;i<720;i++)
      {
        storage[i]=val1;
      }
  }
}

Getting the following error message

Arduino: 1.7.10 (Windows 8.1), Board: "Arduino Uno"

array.ino: In function 'void setup()':

array.ino:13:16: error: no matching function for call to 'HardwareSerial::print()'

array.ino:13:16: note: candidates are:

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26:0,

from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,

from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:223,

from array.ino:2:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:58:12: note: size_t Print::print(const __FlashStringHelper*)

size_t print(const __FlashStringHelper *);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:58:12: note: candidate expects 1 argument, 0 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:59:12: note: size_t Print::print(const String&)

size_t print(const String &);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:59:12: note: candidate expects 1 argument, 0 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:60:12: note: size_t Print::print(const char*)

size_t print(const char[]);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:60:12: note: candidate expects 1 argument, 0 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:61:12: note: size_t Print::print(char)

size_t print(char);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:61:12: note: candidate expects 1 argument, 0 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:62:12: note: size_t Print::print(unsigned char, int)

size_t print(unsigned char, int = DEC);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:62:12: note: candidate expects 2 arguments, 0 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:63:12: note: size_t Print::print(int, int)

size_t print(int, int = DEC);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:63:12: note: candidate expects 2 arguments, 0 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:64:12: note: size_t Print::print(unsigned int, int)

size_t print(unsigned int, int = DEC);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:64:12: note: candidate expects 2 arguments, 0 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:65:12: note: size_t Print::print(long int, int)

size_t print(long, int = DEC);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:65:12: note: candidate expects 2 arguments, 0 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:66:12: note: size_t Print::print(long unsigned int, int)

size_t print(unsigned long, int = DEC);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:66:12: note: candidate expects 2 arguments, 0 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:67:12: note: size_t Print::print(double, int)

size_t print(double, int = 2);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:67:12: note: candidate expects 2 arguments, 0 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:68:12: note: size_t Print::print(const Printable&)

size_t print(const Printable&);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:68:12: note: candidate expects 1 argument, 0 provided

Error compiling.

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.

  Serial.print();Why are you trying to print nothing ?