PCF8574 breaks serial communication

Hi!

I'm using original Arduino Uno with PCF8574 expander. If I add library for an expander, communication with my app on PC crashes. App can connect to arduino, there is no error, but when I send instructions to start stepper motor or read something, there is no answer. Drive doesn't move, no data is received. What should I do? I hope there is a solution for my problem :slight_smile:

ochotny_a:
Hi!

I'm using original Arduino Uno with PCF8574 expander. If I add library for an expander, communication with my app on PC crashes. App can connect to arduino, there is no error, but when I send instructions to start stepper motor or read something, there is no answer. Drive doesn't move, no data is received. What should I do? I hope there is a solution for my problem :slight_smile:

OF course there is a solution. Welcome to the Arduino forum.

The problem seems to be a power problem, so draw up a schematic of how everything is wired and include how the power source is connected. And what are you using for power?

Paul

There is a schematic of my circuit (I know, paint...). The power supply is Kemot T-60W 12V 5A. Thanks for response.

To start a motor app sends instruction "x 0 100" (axis direction position). When PCF8574 is not used, i receive correct echo. With the expander the first return message is correct (although drive does not move), but next are only "x".

What is the 'switch" with 5 volt and ground going to it? Are ALL the power supply grounds and the Arduino grounds connected together?

Paul

The switch is endswitch on axis. I connected all GNDs, nothing changed. Funny thing is, I made another program just to blink built in LED. To turn it on i have to send "ON" command via serial port monitor and use the switch connected to the expander. It works correct so I don't think it's electrical problem.

#include <PCF8574.h>
#include <TimerOne.h> 

#include "step_drive.h"
#include "control_and_comm.h"

PCF8574 expander;
Axis os_X(15, 8, 9); //utworzenie osi, enable, step, dir
Axis os_Y(14, 6, 7); //utworzenie osi, enable, step, dir
//Axis os_Z(15, 12, 13);
Axis obrot(16, 10, 11);
Axis dozownik(17, 2, 3);

int read_index=0;
String seq_tab[100];
bool read_sequence=0;
bool check=0;
bool dispense_flag=0;

bool move_x_flag=0, move_y_flag=0, dose_flag=0, rot_flag=0;

char ax=' ';
int steps_X=0;
int steps_Y=0;
int steps_rot=0;
int steps_dose=0;

bool dir=0;
String steps_temp;
int disp_stage=0; //etap dozowania
String data=""; 
bool sequence_on=false; 
int com_idx; //indeks wykonywania komendy ruchu
bool axis_ready=false; 


bool kranc_x1;
bool kranc_x2;
bool kranc_y1;
bool kranc_y2;
bool kranc_z1;
bool kranc_z2;

void step_interrupt()
{
  
   // digitalWrite(13, digitalRead(13)^1);
  if(os_X.ON) 
  {
    if(os_X.move_axis())
    {
      os_X.ON=0;
      axis_ready=true;
    }
  }
   /////////////////////////////////////////////
  if(os_Y.ON) 
    {
      if(os_Y.move_axis()) 
      {
        os_Y.ON=0;
        axis_ready=true;
      }
    } 
}
void setup() {
 
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT); 
  pinMode(13, OUTPUT); 
  
  expander.begin(0x20);
  expander.pinMode(0, INPUT);
  Serial.begin(9600);
  Timer1.initialize(800);
  Timer1.attachInterrupt(step_interrupt);
  
  for (int i=0; i<100; i++) seq_tab[i]=i;
}

void loop() {
  /*****************COMMUNICATION*********************/
  if(Serial.available()>0) 
  {
    data=Serial.readStringUntil('\n');
    Serial.println(data);
     
  }
    if(data=="seq off")
    {
      read_sequence=false;
      read_index=0;
      data="";
    }
    if(data=="check_table")
    {
      check=true;
      data="";
    }
    if(data=="seq on")
    {
      read_sequence=true;
      read_index=0;
      data="";
    }
    if(data=="dose")
    {
      dispense_flag = 1;
      data="";
    }
    if(data=="clear table")
    {
      for (int i=0; i<100; i++) seq_tab[i]='0';
      data="";
    }
    if(data=="start seq")
    {
      sequence_on=true;
      axis_ready=true;
      com_idx=0;
      data="";
    }
    if(data=="relay_on")
    {
    digitalWrite(4,HIGH);
    Serial.println(" Przekaznik on");
    data="";
    }
   if(data=="relay_ff")
    {
       digitalWrite(4,LOW);
       Serial.println(" Przekaznik off");
       data="";
    }
      /***********DECODE COMMAND***********/
    ax=read_axis(data);
    dir=read_dir(data);
    if(data[0]=='x') 
    {
      steps_X=read_steps(data);
     // Serial.println(data[4]);
      digitalWrite(13, HIGH);
    }
    if(ax=='y') steps_Y=read_steps(data);
    //if(ax=='a') steps_rot=read_steps(data); //obrot
    //if(ax=='b') steps_dose=read_steps(data); //dozownik
    data="";
   /**********EXECUTE SEQUENCE**********/
   if(sequence_on && axis_ready)
   {
    if(com_idx==101 || seq_tab[com_idx]=='0') sequence_on=false;
      Serial.println("Wczytanie komendy");
      data=seq_tab[com_idx];
      com_idx++;
      axis_ready=false;
  /********DECODE COMMAND********/
    ax=read_axis(data);
    dir=read_dir(data);
    if(ax=='x') steps_X=read_steps(data);
    if(ax=='y') steps_Y=read_steps(data);
    if(ax=='a') steps_rot=read_steps(data); //obrot
    if(ax=='b') steps_dose=read_steps(data); //dozownik
   }

   if(read_sequence)
    {
      seq_tab[read_index]=data;
      read_index++;
    }
  /***********MOVE AXIS******************/
  if(read_sequence==false)
  {
    if(check)
    {
      for(int i=0; i<100; i++)
      {
        Serial.println(seq_tab[i]);
      }
      check=0;
      //Serial.println("CoordX "+ os_X.get_pos());
      //Serial.println("CoordY "+ os_Y.get_pos());
    }
    if(ax=='x' && steps_X!=os_X.get_pos()) 
    {
      os_X.ON=1;
      os_X.MoveTo(steps_X);
      ax=' ';
    }
    if(ax=='y' && steps_Y!=os_Y.get_pos()) 
    {
      os_Y.ON=1;
      os_Y.MoveTo(steps_Y);
      ax=' ';
    }

     if(ax=='a') 
    {
      rot_flag=1;
      ax=' ';
    }
    
    if(ax=='b') 
    {
      dose_flag=1;
      ax=' ';
    }
  }
}

After some tests I noticed that communication is ok, but adding mentioned earlier library somehow affects my own functions. I wrote a function to extract amount of steps from command. Without PCF8574.h it works, but with it, program never gets into if(). I checked it by turning on built in LED. There is also a Serial.println() which sends empty message or is not working.

int read_steps(String command)
{
  
  String steps_temp;
  steps_temp=command[4];
  int steps;
   if(command.length()>5)
    {
          digitalWrite(13, HIGH);
      for (int i=5; i<command.length(); i++)
      {
        steps_temp=String(steps_temp+command[i]);
      }
    }
    Serial.println(steps_temp);
    steps=steps_temp.toInt();
    return steps;
}

ochotny_a:
After some tests I noticed that communication is ok, but adding mentioned earlier library somehow affects my own functions. I wrote a function to extract amount of steps from command. Without PCF8574.h it works, but with it, program never gets into if(). I checked it by turning on built in LED. There is also a Serial.println() which sends empty message or is not working.

int read_steps(String command)

{
 
  String steps_temp;
  steps_temp=command[4];
  int steps;
  if(command.length()>5)
    {
          digitalWrite(13, HIGH);
      for (int i=5; i<command.length(); i++)
      {
        steps_temp=String(steps_temp+command[i]);
      }
    }
    Serial.println(steps_temp);
    steps=steps_temp.toInt();
    return steps;
}

One thing, right away, jumps out to me, is the use of "String". The use of String in larger computer systems will cause a "garbage collection" function to run which reclaims memory used by the String function. The Arduino does not have that capability. The standard is the use the "string" instead.

IF you determined the error may be occurring at an "if", then you need to print the values being tested so you can debug the logic.

Paul