Hello.
I recently salvaged an old printer and I was able to retrieve the bed for linear motion with an linear encoder, strip and a DC motor.
I was successful to jack in the encoder to Arduino and see the positions of the print head(When I moved it with my hands).
I than stored the position values in the EEPROM flash memory of Arduino with a button click and replayed the position on the serial monitor with another button click.
What I want to do is move the print head by my hand and record the positions with the first button click and then after clicking the second button I want the print head to move automatically to the positions I moved it previously.
I do not want a very sophisticated PID control for it. I'm a tinkerer and want to start step by step. A help with code snippet for the part of motor control to go to targeted positions as recorded would be helpful.
The code till now I've written is
#include <EEPROM.h>
uint8_t recordButtonPin = 11;
uint8_t playButtonPin = 10;
//uint8_t ledPin = 13;
#define SAMPLE_DELAY 25
// Interrupt information
// 0 on pin 2
// 1 on pin 3
#define encoderI 2
#define encoderQ 3 // Only using one interrupt in this
volatile int count;
const int motorPinA = 12;
const int motorPinB = 13;
void setup(){
Serial.begin(115200);
count=0;
pinMode(encoderI, INPUT);
pinMode(encoderQ, INPUT);
attachInterrupt(0, handleEncoder, CHANGE);
pinMode(recordButtonPin, INPUT);
digitalWrite(recordButtonPin, HIGH);
pinMode(playButtonPin, INPUT);
digitalWrite(playButtonPin, HIGH);
//pinMode(ledPin, OUTPUT);
Serial.println("Linear Encoder recorder/player");
pinMode(motorPinA, OUTPUT);
pinMode(motorPinB, OUTPUT);
}
void loop(){
// Serial.println(count);
// delay(10);
if (! digitalRead(recordButtonPin)) {
delay(10);
// wait for released
while (! digitalRead(recordButtonPin));
delay(20);
// OK released!
recordEncoder();
}
if (! digitalRead(playButtonPin)) {
delay(10);
// wait for released
while (! digitalRead(playButtonPin));
delay(20);
// OK released!
spitEncoder();
}
}
void handleEncoder(){
if(digitalRead(encoderI) == digitalRead(encoderQ))
{
count++;
}
else{
count--;
}
}
void recordEncoder(){
uint16_t addr = 0;
Serial.println("Recording Position");
while (digitalRead(recordButtonPin)){
// Serial.print("Actual count: ");
//Serial.println(count);
volatile int constrainedCount = constrain(count, 0, 4000);
volatile int mappedCount = map(constrainedCount, 0, 4000, 0, 255);
Serial.print("mapped count: ");
Serial.println(mappedCount);
EEPROM.write(addr, mappedCount);
addr++;
if (addr == 512) break;
delay(SAMPLE_DELAY);
}
if (addr != 512) EEPROM.write(addr, 255);
//digitalWrite(ledPin, LOW);
Serial.println("Done Recording");
delay(250);
// return();
}
void spitEncoder(){
uint16_t addr = 0;
Serial.println("Spitting what you just recorded");
while (digitalRead(playButtonPin)){
volatile int x = EEPROM.read(addr);
if (x == 512) break;
Serial.println(x);
delay(SAMPLE_DELAY);
addr++;
if (addr == 512) break;
}
//if (addr != 512) EEPROM.read(addr);
Serial.println("Done Spitting");
delay(250);
//return();
}
void moveForward(){
digitalWrite(motorPinA, HIGH);
digitalWrite(motorPinB, LOW);
}
void moveBackward(){
digitalWrite(motorPinA, LOW);
digitalWrite(motorPinB, HIGH);
}
I'm struggling with the logic for my next part of using the stored position data to control the DC motor simply and not with a Kp Ke etc etc PID equations ..
Advance bunch of thanks
Pseudo code :
if(pos != old pos){
if(pos>old pos){
move forward // or backward
}
if(pos?old pos){
move opposite direction
}
}
if(pos == old pos){
........
I don't know how to direct the motor for the next logged position
........
}