Usage of several controllers

Hi,

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.

mechatron:
Hi,

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 ?

This is the project I have 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 ?

Yeh, with that code you're nowhere near the load capacity of an arduino.

So, you only need one arduino. What problem are you having such that you think you need more than one?

Hi,

I'm still building the actual linear servo so I have experienced no problems so far. (It takes long for the parts to arrive from China)

I thought to plan ahead and separate the functions to avoid any possible trouble. And to learn how to use multiple controllers at once.

it takes quite a while for the code to continue

 delay(2000);

Like, two seconds?

Ouch!!! :-* (debugging delay causing a "bug")

mechatron:
I thought to plan ahead and separate the functions to avoid any possible trouble. And to learn how to use multiple controllers at once.

You can separate the functions, without using multiple uCs. Don't use multiple controllers unless you have a really good reason to.

At 9600 baud your serial will still be turtle slow to Arduino. On your scale, 10 minutes between chars available.

At least use SPI bus!

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.

...R

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.