I'm asking myself how I could use several micro controllers to perform one task.
In this case I would like to have a dedicated encoder (or in general a sensor) read out chip and a dedicated PID controller chip.
When the PID uC goes through its code it should ask (I think this is called polling) the encoder chip what the value of encoder pulses is and use it in its algorithm. This would free up the capacity of both chips to perform the designated tasks to perfection I think.
I this example the communicated messages would only have to be something like:
PID chip to encoder chip:
"encoderValue?".
encoder chip to PID chip:
"1" or "2" or "3" or "4651" or "30000123" and so on.
I'm asking myself how I could use several micro controllers to perform one task.
In this case I would like to have a dedicated encoder (or in general a sensor) read out chip and a dedicated PID controller chip.
When the PID uC goes through its code it should ask (I think this is called polling) the encoder chip what the value of encoder pulses is and use it in its algorithm. This would free up the capacity of both chips to perform the designated tasks to perfection I think.
I this example the communicated messages would only have to be something like:
PID chip to encoder chip:
"encoderValue?".
encoder chip to PID chip:
"1" or "2" or "3" or "4651" or "30000123" and so on.
I'm not sure what the question is but sure, you could do that. One easy way would be to connect the uCs using their serial ports, if the serial port transmission speed is fast enough for your purpose.
I would like to have a dedicated encoder (or in general a sensor) read out chip and a dedicated PID controller chip.
Are you doing this because you think that one Arduino is not up to doing it alone ? In your simple example I would have thought that the overhead of doing the communications would outweigh the burden of one Arduino doing both tasks. Do you have a more complicated project in mind ?
Best way to explain is to show it. In the function zero there will be a procedure to set the servo to its zero point. Performed once at start up. Code is written from bits and pieces I found on the internet and put them together in one code.
There are some read.write lines in it for debugging.
Serial communication is not a very fast way to communicate I think. When I enter a new Set point it takes quite a while for the code to continue. At least it takes a while for the serial monitor to continue.
int sensor_A;
int sensor_B;
int readValue = 0;
int readValueOld;
int step;
int Setpoint = 0;
unsigned long sampleTime = 1500, x, millisStart; // x is the range of the linear servo
double Output, OutputOld;
double /*errSum,*/ lastErr = 0; // errSum is not defined as this sketch is used for position control
double kp, /*ki, */ kd; // ki is not defined as this sketch is used for position control
double errorOld, error;
double dErr;
#define SENSOR_PIN_A A4 // Sensor input 1 on analog pin 4
#define SENSOR_PIN_B A5 // Sensor input 2 on analog pin 5
#define PWM1 6 // PWM1 output on digital pin 6
#define PWM2 7 // PWM2 output on digital pin 7
void setup(){
Serial.begin(9600);
zero();
analogWrite(PWM1, 0); // Protect the H-bridge from a shortcut at the start
analogWrite(PWM2, 0); // Protect the H-bridge from a shortcut at the start
sampleTime = 100;
x = 3000; // Enter the range of the linear servo here
pinMode(SENSOR_PIN_A, INPUT);
pinMode(SENSOR_PIN_B, INPUT);
pinMode(PWM1, OUTPUT);
pinMode(PWM2, OUTPUT);
sensor_A = digitalRead(SENSOR_PIN_A);
sensor_B = digitalRead(SENSOR_PIN_B);
if(sensor_A == 0 && sensor_B == 0) {
step = 0;
}
if(sensor_A == 0 && sensor_B == 1) {
step = 1;
}
if(sensor_A == 1 && sensor_B == 1) {
step = 2;
}
if(sensor_A == 1 && sensor_B == 0) {
step = 3;
}
kp = 10; // Tune kp here in sketch
/* ki = 0; */ // ki is not defined as this sketch is used for position control
kd = 10; // Tune kd here in sketch
Serial.begin(9600);
Serial.print("Beginstand encoder: ");
Serial.println(step);
millisStart = millis();
}
void loop(){
sensor_A = digitalRead(SENSOR_PIN_A);
sensor_B = digitalRead(SENSOR_PIN_B);
if(sensor_A == 0 && sensor_B == 0){
if(step == 1){
readValue--;
}
if(step == 3){
readValue++;
}
step = 0;
}
if(sensor_A == 0 && sensor_B == 1){
if(step == 2){
readValue--;
}
if(step == 0){
readValue++;
}
step = 1;
}
if(sensor_A == 1 && sensor_B == 1){
if(step == 3){
readValue--;
}
if(step == 1){
readValue++;
}
step = 2;
}
if(sensor_A == 1 && sensor_B == 0){
if(step == 0){
readValue--;
}
if(step == 2){
readValue++;
}
step = 3;
}
if(readValue != readValueOld)
{
Serial.println(readValue);
readValueOld = readValue;
}
if(millis() - millisStart >= sampleTime)
{
millisStart = millis();
if (Serial.available() > 0) // if we get a valid byte, read analog ins:
{
Setpoint = Serial.parseInt();
// Setpoint = (Serial.read()); // get incoming byte:
}
if (Setpoint > x)
{
Setpoint = x; // If Setpoint is greater then the range of the servo make x the end position
}
else if(Setpoint < 0)
{
Setpoint = 0; // If Setpoint is bellow the zero position of the servo make 0 the start position
}
double error = Setpoint - readValue;
/* errSum += (error * sampleTime);*/ // errSum is not used as this sketch is used for position control
double dErr = (error - lastErr) / sampleTime;
/*Compute PID Output*/
Output = kp * error + /* ki * errSum + */ kd * dErr; // ki*errSum is not used as this sketch is used for position control
if(Output > 255)
{
Output = 255;
}
if(Output < -255)
{
Output = -255;
}
errorOld = error;
errorOld = abs(errorOld);
if(errorOld < 5)
{
Serial.print("errorOld = ");
Serial.println(errorOld);
analogWrite(PWM1, 0);
analogWrite(PWM2, 0);
}
else
{
if(Output > 0)
{
analogWrite(PWM2, 0);
Output = map (Output, 0, 255, 0, 255);
analogWrite(PWM1, Output);
Serial.print("Ouput PWM1 = ");
Serial.println(Output);
Serial.print("Setpoint = ");
Serial.println(Setpoint);
}
else
{
if(Output < 0)
{
analogWrite(PWM1, 0);
Output = abs(Output);
Output = map (Output, 0, 255, 0, 255);
analogWrite(PWM2, Output);
Serial.print("Ouput PWM2 = ");
Serial.println(Output);
}
}}
/*Remember some variables for next time*/
lastErr = error;
}
}
void zero()
{
Serial.println("bladibla");
delay(2000);
}
Nothing in that code looks particularly onerous for one Arduino. The parseInt function is blocking so may slow down the execution of the code. Are you currently having problems with the speed of operation ?
If you want simple reliable non-blocking code for receiving serial data look at serial input basics
If the serial data you need is less than 63 bytes long it will all fit in the Arduino input buffer while your program is doing other stuff. Then you can read it quickly when convenient.
Dealing with communication between arduinos will make your system harder to build and much harder to debug. Obviously, sometimes it's necessary, but if you actually do have a performance problem with your existing build, I'd try to solve it with faster hardware initially.