Serial not outputting anything

See attached code. For some reason it's not outputting anything to serial. I've confirmed my board works fine as I tested it with another code that does output to serial. Any suggestions why this won't output to serial?

#define ENCA 2
#define PWM 10
int pos = 0;
long prevT = 0;
float eprev = 0;
float eintegral =0;

void setup() {
  pinMode(ENCA,INPUT);
  Serial.begin (9600);
  attachInterrupt(digitalPinToInterrupt(ENCA),readEncoder,RISING);
}

void loop() {
  int target = 300;   
  float kp = 50;
  float ki = 0.05;
  float kd = 0;

  long currT = micros();
  float deltaT = ((float)(currT-prevT))/1.0e6;
  prevT = currT;
  // ERROR
  int e = target - pos;
  // KD
  float dedt = (e - eprev)/(deltaT);
  // KI
  eintegral = eintegral + e*deltaT;
  // CONTROL SIGNAL
  float u = kp*e + ki*eintegral + kd*dedt; 
  // MOTOR POWER
  float pwr = fabs(u);
  if (pwr>255){pwr = 255;}
  // to motor
  setMotor(pwr,PWM);
  // prev error
  eprev = e;
  // printing
  Serial.print(target);
  Serial.print(" ");
  Serial.print(pos);
  Serial.println();
}
void setMotor(int pwmVal,int pwm){
  analogWrite(pwm,pwmVal);
  }

void readEncoder() {
  int a = digitalRead (ENCA);
  if (a>0){pos++;}  
}

I see nothing wrong with the code that could affect serial.

However, variables shared with interrupt routines (like pos) must be declared volatile, and multibyte variables shared variables (like pos) must be protected from corruption while being accessed by the main program.

Check the wiring. Is the serial monitor set to 9600 Baud?

The trigger level of the interrupting signal is rising edge and ENCA-pin (DPin-2) momentarilly goes HIGH which you are reading. It is possible that you might missing the reading of the logic evel of such a short pulse. Are you counting the number of interrupt? If yes, then just advance a counter (pos) in the ISR.

Suggesting:

volatile int pos = 0;    //put in the global area
void readEncoder() 
{
  pos++;  
}

I made the modification, but still nothing in serial. I also have the issue that this keeps moving the DC motor forever and never stops it. I confirmed my setup is correct because another code does work. Here's the updated code:

#define ENCA 2
#define PWM 10
volatile int pos = 0;
long prevT = 0;
float eprev = 0;
float eintegral =0;

void setup() {
  pinMode(ENCA,INPUT);
  Serial.begin (9600);
  attachInterrupt(digitalPinToInterrupt(ENCA),readEncoder,RISING);
}

void loop() {
  int target = 50;   
  float kp = 100;
  float ki = 0.14;
  float kd = 0;

  long currT = micros();
  float deltaT = ((float)(currT-prevT))/1.0e6;
  prevT = currT;
  // ERROR
  int e = target - pos;
  // KD
  float dedt = (e - eprev)/(deltaT);
  // KI
  eintegral = eintegral + e*deltaT;
  // CONTROL SIGNAL
  float u = kp*e + ki*eintegral + kd*dedt; 
  // MOTOR POWER
  float pwr = fabs(u);
  if (pwr>255){pwr = 255;}
  // to motor
  setMotor(pwr,PWM);
  // prev error
  eprev = e;
  // printing
  Serial.print(target);
  Serial.print(" ");
  Serial.print(pos);
  Serial.println();
}
void setMotor(int pwmVal,int pwm){
  analogWrite(pwm,pwmVal);
  }

void readEncoder() 
{
  pos++;  
}

This is the code I tested with that does work (although it has the issue of incrementing the DC motor imprecisely, but that's besides the point) however it prints everything constantly on the same line instead of new line even though I have NL & Return carriage enabled in serial.

I'm using RS485 with Arduino Leonardo on a custom board, just the bare minimums required on the Leonardo to make it work.

#include <PID_v1.h>

//Motor definitions and variables
#define MotorA_CW_pin 10
#define MotorA_CCW_pin 9
boolean motorAstopped=true;//true -> motor A is stopped. false -> Motor A is running

//Encoder definitions and variables
#define steps_per_mm 307 //how many steps should encoder count to move 1mm (was 307)                  //------ CAN BE CHANGED BY USER
#define debounce_del 2 //debounce time needed for the encoder                                //------ CAN BE CHANGED BY USER
#define EncoderA_pin 2 //encoder is connected to this pin in MCU
#define fix_param 0
int stepsenc;//stores how many pulses encoder needs to move distancemm
unsigned long encoder_stepsA=0;
unsigned long encoder_stepsB=0;
int lasthigh=2;//stores encoder status, 0 -> low, 1 -> high, 2-> invalid
int distancemm=2;//distance in mm to move                                                    //------ CAN BE CHANGED BY USER
boolean SAR;//Stores encoder value (low or high)
unsigned long tmr_debounce;//Stores the time remaining until debounce_del is finished

//Serial communication definitions and variables
#define serial_enable_pin A5
boolean debugEN=true;//Activate or deactivate serial data debug

//PID VALUES
double Setpoint, Input, Output;
double Kp=100, Ki=500, Kd=50;                                                              //------ CAN BE CHANGED BY USER
//If component does not reach enough distance, increase P, if it moves larger distance than needed, increase I
// Kp=50, Ki=100, Kd=0; 
// P = POWER
// I and D = How much decreament in power should happen when motor is about to reach destination
// I mainly affects power
// D mainly afects smoothness
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

unsigned long tmrzz,tmryy;
int err[50];
boolean onebrake=true;

void setup() {
  for(int i=0;i<50;i++){
    err[i]=0;
  }
  
  Serial.begin(57600);
  pinMode(MotorA_CW_pin,OUTPUT);
  pinMode(MotorA_CCW_pin,OUTPUT);
  pinMode(serial_enable_pin,OUTPUT);
  analogWrite(MotorA_CW_pin,0);
  analogWrite(MotorA_CCW_pin,0);
  pinMode(EncoderA_pin, INPUT_PULLUP);
  pinMode(A4,INPUT_PULLUP);
  //attachInterrupt(digitalPinToInterrupt(EncoderA_pin), Read_encoderA, CHANGE);
  myPID.SetMode(AUTOMATIC);   //set PID in Auto mode
  myPID.SetSampleTime(1);  // refresh rate of PID controller
  myPID.SetOutputLimits(0,255);                            ///////////////////////// PID POWER (0 -  255)
}

void loop() {
  stepsenc=distancemm*steps_per_mm;

  Setpoint = stepsenc - (encoder_stepsB - fix_param);
  write_data_serial("Setpoint: ");
  write_data_serial(String(Setpoint));
  write_data_serial("\n");

  encoder_stepsB=0;
  
  motorAstopped=false;
  lasthigh=2;
  encoder_stepsA=0;
  Input=0;

  tmrzz=millis();
  onebrake=true;
  while(tmrzz+3000>millis()){
    if(encoder_stepsA<Setpoint){
      myPID.Compute();
      if(encoder_stepsA>Setpoint*0.85){
        //Output=Output*0.9;
      }
      analogWrite(MotorA_CW_pin,Output);
      tmrzz=millis(); //loop timer
    }
    else if(onebrake==true){
      analogWrite(MotorA_CW_pin,0);
      analogWrite(MotorA_CCW_pin,255);
      tmryy==millis();
      onebrake=false;
    }
    
    SAR=digitalRead(2);
    
    if(SAR==true && lasthigh!=1 && tmr_debounce+debounce_del<=micros()){
      encoder_stepsA++;
      //if(encoder_stepsA>=stepsenc){break;}
      lasthigh=1;
      tmr_debounce=micros();
    }
    else if(SAR==false && lasthigh!=0  && tmr_debounce+debounce_del<=micros()){
      encoder_stepsA++;
      //if(encoder_stepsA>=stepsenc){break;}
      lasthigh=0;
      tmr_debounce=micros();
    }
    Input=encoder_stepsA;

    if(onebrake==false && tmryy+50<=millis()){  ////////////// BRAKE TIME is 12500 uS
      analogWrite(MotorA_CCW_pin,0);
    }
    
  }
  
  analogWrite(MotorA_CW_pin,0);
  
  encoder_stepsB=encoder_stepsA-Setpoint;
  write_data_serial("Actual Steps: ");
  write_data_serial(String(encoder_stepsA));
  write_data_serial("\n");
  write_data_serial("Error: ");
  write_data_serial(String(encoder_stepsB));
  write_data_serial("\n");
  err[0]=encoder_stepsB;

  encoder_stepsA=0;
  Input=0;
  
  delay(2000);
}

void Read_encoderA(){
    encoder_stepsA++;
    if(encoder_stepsA>=stepsenc){
      analogWrite(MotorA_CW_pin,255);
      motorAstopped=true;
    }
    delay(debounce_del);//debounce time
}

//This function receives String of data, and writes it on serial for debugging
void write_data_serial(String dat){
  if(debugEN==true){
    digitalWrite(serial_enable_pin,HIGH);
    delay(10);
    Serial.print(dat);
    delay(10);
    digitalWrite(serial_enable_pin,LOW);
    delay(100);
  }
}

I have tested your code with an Arduino Uno in the Serial Monitor came "300 0" spammed.
Check the "RX" Led if is on then you have already done nothing wrong with the upload possible problem: wrong Baud rate

Upload the following sketch as a test purpose and check that you see something changing in the Serial Monitor. Be sure that you have a 2.2k to 4.7k external pull-down resistor at DPin-2.

#define ENCA 2
volatile int pos = 0;
volatile bool flag = false;

void setup() 
{
    Serial.begin (9600);
    attachInterrupt(digitalPinToInterrupt(ENCA) ,readEncoder, RISING);
}

void loop() 
{
   if (flag == true)
   {
       Serial.println(pos, DEC);
       flag = false;
   }
}

void readEncoder() 
{
  pos++;
  flag = true;  
}

Just tried uploading this and nothing was being printed. But my motor also didn't move. Any idea why my other code is only printing on the same line?

Here's how it looks like when my other code prints results, just keeps adding it on same line: Imgur: The magic of the Internet

1. Connect switch K1 (the interrupting devicee) as per Fig-1.

intZeroX
Figure-1:

2. Upload the following sketch.

#define ENCA 2
volatile int pos = 0;
volatile bool flag = false;

void setup() 
{
    Serial.begin (9600);
    pinMode(2, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(ENCA) ,  readEncoder, LOW);
}

void loop() 
{
   if (flag == true)
   {
       Serial.println(pos, DEC);
       flag = false;
   }
}

void readEncoder() 
{
  pos++;
  flag = true;  
}

3. Gently, press and release K1. Check that a value has appeared on Serial Monitor.
4. Repeat Step-3 and check that value in Serial Monitor chnages.

change "Both NL & CR" to "New line"

Why? Is the UNO receiving any command/data from the InputBox (Fig-1) of Serial Monitor?


Figure-1:

I was just saying how it works for me.

It outputs for me. I don't have an encoder connected to pin 2 so it just shows "300 0" over and over.

Did you remember to set the baud rate on Serial Monitor the same as your sketch?

Could whatever is connected to Pin 10 be drawing too much power and causing your sketch to reset?

But it shouldn't show 300 over and over. It should print more than that like "target" and "pos"

It prints the VALUE of 'target' (300) and the VALUE of 'pos' (0). Since I don't have an encoder to change 'pos' and 'target' never changes, I get "300 0".

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.