Recent

Author Topic: PC to RS485 to Arduino  (Read 5278 times)

bvn123

  • New Member
  • *
  • Posts: 17
Re: PC to RS485 to Arduino
« Reply #15 on: November 08, 2020, 09:57:32 pm »
You send commands only from PC to Arduino - one sided transmission.
First of all check the power on the both MAX485 (it should be 3V3 or 5V).
Then check ~RE\DE pins of both MAX485 when the program is running.
These pins ~RE and DE should be shorted for each MAX485.
On PC side it should be HIGH state (3V3 or 5V for transmitting), and LOW state (about 0V for receiving) on arduino side.
You may use multimeter or even LED + R (300..500 Ohm) to control the voltage. Use proper LED polarity.

If this isn't so on PC side, change the state of the control pin MAX485 in PC program.
As I see, in PC's program (in Your Lazarus code)
  ser.RTS := false; // comment this if needed
  ser.DTR := false; // comment this if needed
- try to change FALSE to TRUE state for the RTS, then for DTR parameter - obviously one of these two controls the work direction of MAX485,
if the pin state is uncorrect on Arduino side - Arduino also tries to transmit data, so You should find appropriate code to contol ~RE\DE pins of the 2nd MAX485.


ccrause

  • Hero Member
  • *****
  • Posts: 856
Re: PC to RS485 to Arduino
« Reply #16 on: November 09, 2020, 07:06:54 am »
Here is diagram  dongle, max485, and Arduino Nano,

Dongle A to A on Max485 (first one)   
Dongle B to B on Max485 (first one)

First Max485 A to A on Second Max485
First Max485 A to A on Second Max485

First Max485 DI to first Nano TX
First Max485 DE to first Nano D2
First Max485 RE to first Nano D2
First Max485 RO to first Nano RX

Second Max485 DI to second Nano TX
Second Max485 DE to second Nano D2
Second Max485 RE to second Nano D2
Second Max485 RO to second Nano RX
It seems like this connection should work.  Are you using a bare Max485 chip or a board/module. The signal lines needs terminating resistors which should be present on a module, but you have to provide if using a bare max485. Unfortunately I cannot test this (no Max485...). A photo of you setup would also help in understanding your hardware configuration.  It would also help if you can post a link to the USB dongle you are using.

Quote
I am not sure how to write the code for it.
#define DE_RE   2

Is this right?
That is one way of defining a constant.  Because your earlier Arduino code used int I would stick with that style. Below an adaption of your earlier Arduino code to pull RE and DE low, so that the Max485s can transmit data to the Arduino(s).
Code: C  [Select][+][-]
  1.     int led2 = 3;   // D3 Pin 6
  2.     int led3 = 4;   // D4 Pin 7
  3.     int RE_DE = 2;
  4.  
  5.     void setup()
  6.     {
  7.         pinMode(led2, OUTPUT); // Set pin 6 as digital out
  8.         pinMode(led3, OUTPUT); // Set pin 7 as digital out
  9.  
  10. // Put Max485 in transmit mode so that Arduino can receive messages
  11.         pinMode(RE_DE, OUTPUT);
  12.         digitalWrite(RE_DE, LOW);
  13.  
  14.     // Start up serial connection
  15.         Serial.begin(9600); // baud rate
  16.         Serial.flush();
  17.     }

In the loop function (referring to code posted on Nov 3) you should also clear the variable input once a complete command has been received and executed.  Once this is fixed you should be able to send commands to both Arduinos at once.  Get this working before trying to send commands to individual Arduinos.  I suspect your PC serial code should work to broadcast the messages to all the connected slaves.

bvn123

  • New Member
  • *
  • Posts: 17
Re: PC to RS485 to Arduino
« Reply #17 on: November 09, 2020, 09:25:34 am »
If MAX485 is not this one (IC only; on self-made PCB ~RE & DE mostly are shorted)
https://datasheets.maximintegrated.com/en/ds/MAX1487-MAX491.pdf

but this (module):
https://umnyjdomik.ru/modul-preobrazovatelya-interfejsov-uart-ttl-rs-485-na-max485.html
the last one has unshorted pins ~RE & DE,

so in Your Lazarus code both should be FALSE:
  ser.RTS := false; // comment this if needed
  ser.DTR := false; // comment this if needed
or both TRUE:
  ser.RTS := true;   
  ser.DTR := true;

supposedly the last is correct (if 'true' corresponds to HIGH pin state (3V3 or 5V)).

Actually to hold constantly RS-485 line in busy state isn't good, because the cable is wearing out :D. In reality this is harder state for IC and for power supply source.
You should set MAX485 to transmitting state only for transmitting time.
Also You wrote about some number of the devices You'd like to connected to Your cable.
If each one will have separate MAX485 module, You should leave the terminal resistors 120 Ohm only on the 2 modules, which are placed on the ends of the cable. The rest number of resistors 120 Ohm should be dismantled.
« Last Edit: November 09, 2020, 10:28:24 am by bvn123 »

microguy

  • New Member
  • *
  • Posts: 49
Re: PC to RS485 to Arduino
« Reply #18 on: November 20, 2020, 04:25:17 am »
Sorry for the delay. I start over again and got Arduino working with Serial Monitor from Arduino IDE and got RS485 working too but something is missing. When I use the Serial monitor on Arduino and got it working as 1 for LED13 turn on the light, 2 for LED13 turn off the light, 3 for LED3 turn on the light, 4 for LED3 turn off the light. So forth.....

When I use Lazarus. I have two buttons - one button for turn off the LED light off and the other one for turn it off. When I start the program and all LED lights are off. When I hit the ON button and nothing happen. When I hit the OFF button and the LED 13 light comes on. When I hit the ON button and LED 13 light went off.  It is not right and should be backward. I could not figure out what went wrong on Lazarus code.

See the code for Arduino below
int RE_DE = 2;

void setup()
{
  pinMode(13, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6, OUTPUT),
  pinMode(7, OUTPUT);

// Put Max485 in transmit mode so that Arduino can recieve message
  pinMode(RE_DE, OUTPUT);
  digitalWrite(RE_DE, LOW);

// Start up serial connection
  Serial.begin(9600);

while (!Serial);  // not sure what is this

// for serial monitor?
Serial.println("Input 1 to Turn LED on and 2 to off");
}

void loop()
{
  if (Serial.available())
    {
    int state = Serial.parseInt();
    if (state == 1)
      {
      digitalWrite(13, HIGH);
      Serial.println("Command completed LED 13 turned ON");
      }
    if (state == 2)
      {
      digitalWrite(13, LOW);
      Serial.println("Command completed LED 13 turned OFF");
      }
    if (state == 3)
      {
      digitalWrite(3, HIGH);
      Serial.println("Command completed LED 3 turned ON");
      }
    if (state == 4)
      {
      digitalWrite(3, LOW);
      Serial.println("Command completed LED 3 turned OFF");
      }
    if (state == 5)
      {
      digitalWrite(4, HIGH);
      Serial.println("Command completed LED 4 turned ON");
      }
    if (state == 6)
      {
      digitalWrite(4, LOW);
      Serial.println("Command completed LED 4 turned OFF");
      }
    if (state == 7)
      {
      digitalWrite(5, HIGH);
      Serial.println("Command completed LED 5 turned ON");
      }
    if (state == 8)
      {
      digitalWrite(5, LOW);
      Serial.println("Command completed LED 5 turned OFF");
      }
    if (state == 9)
      {
      digitalWrite(6, HIGH);
      Serial.println("Command completed LED 6 turned ON");
      }
    if (state == 10)
      {
      digitalWrite(6, LOW);
      Serial.println("Command completed LED 6 turned OFF");
      }
    if (state == 11)
      {
      digitalWrite(7, HIGH);
      Serial.println("Command completed LED 7 turned ON");
      }
    if (state == 12)
      {
      digitalWrite(7, LOW);
      Serial.println("Command completed LED 7 turned OFF");
      }
    }
}

Here is the code for Lazarus
procedure TForm1.Button1Click(Sender: TObject);
begin
     ser.SendString('1'); // button 1 should have 'off' here
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ser.SendString('2'); // button 2 should have 'on' here

procedure TForm1.FormCreate(Sender: TObject);
begin
  ser := TBlockSerial.Create;
  Sleep(250);
  ser.Connect('COM5'); // write here Arduino COM port number (on linux it's something like '/dev/ttyUSB0')
  Sleep(250);
  ser.Config(9600, 8, 'N', SB1, False, False);
  ser.RTS := false; // comment this if needed
  ser.DTR := false; // comment this if needed
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ser.free;
end;



end;

ccrause

  • Hero Member
  • *****
  • Posts: 856
Re: PC to RS485 to Arduino
« Reply #19 on: November 20, 2020, 07:58:03 am »
When I use Lazarus. I have two buttons - one button for turn off the LED light off and the other one for turn it off. When I start the program and all LED lights are off. When I hit the ON button and nothing happen. When I hit the OFF button and the LED 13 light comes on. When I hit the ON button and LED 13 light went off.  It is not right and should be backward. I could not figure out what went wrong on Lazarus code.
Please post the complete Lazarus project - one possibility is that you hooked up the event handlers for the buttons wrong.  But the connection of event handlers to the button instances are not shown in your code snippet (it is in the .lfm file).

Also use code markers (click on the # button normally above the edit window), it is easier to read code if it is presented with syntax highlighting.

Quote
Code: C  [Select][+][-]
  1. while (!Serial);  // not sure what is this
This code waits for the Serial connection to be opened on boards that use native USB CDC for the serial connection.  This line of code is only needed on boards such as Due, Leonardo, Micro etc., not Uno, Nano, Mega etc.

Almir.Bispo

  • Jr. Member
  • **
  • Posts: 91
  • CSV Comp DB is the Best NoSQL
    • CSV Comp DB (NoSQL)
Re: PC to RS485 to Arduino
« Reply #20 on: November 20, 2020, 04:27:57 pm »
Warning:
On Pascal (Lazarus IDE) ,using sdpo serial component
Code: Pascal  [Select][+][-]
  1. //it means that i sent the byte #48
  2. serial.SendData('0');
  3.  
  4. //it means that i sent the byte #49
  5. serial.SendData('1');
  6.  
  7. //it means that i sent the byte #50
  8. serial.SendData('2');
  9. //so on...
  10.  

On Arduino Code:
Code: C  [Select][+][-]
  1. char cmd;
  2. cmd = serial.input(); //this functions does not exists.You must to adapt on Arduino
  3. if ( cmd==48 ) { do it... } //byte #48 is the '0' (zero)
  4. if ( cmd==49 ) { do it... } //byte #49 is the '1' (one)
so on....

This is my project with rs485 (i did m Hardware based on STM8,Code Editor,etc)
https://www.youtube.com/watch?v=MCO_JhFcSH8

This is about the P-Noise protocol (rs485):
https://app.box.com/s/hm5nhsfyxojdgf9wclsb3bus8jq1krbm
CSV Comp DB Developer {Pascal Lover}

microguy

  • New Member
  • *
  • Posts: 49
Re: PC to RS485 to Arduino
« Reply #21 on: November 21, 2020, 08:36:54 am »
Now I got it working. I got those numbers backward. Ex.  number 1 should be OFF, not ON and number 2 should be ON, not OFF. I change the code in Arduino. Here is the code for Arduino.

Two more things I would like to fix.

First - When I run Serial Monitor and it runs pretty fast. But when I use Lazarus program and it run slower than Serial monitor. Of course, I took out the pinMode(RE_DE, OUTPUT); and digitalWrite(RE_DE, LOW); to get the Serial Monitor working.

Second. I would like to add second Arduino to run. I am not sure how to write the code for Arduino and Lazarus to get some LED light on from second Arduino. I will add second Max485 on second Arduino.

int RE_DE = 2;

void setup()
{
  pinMode(13, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6, OUTPUT),

// Put Max485 in transmit mode so that Arduino can recieve message
  pinMode(RE_DE, OUTPUT);
  digitalWrite(RE_DE, LOW);

// Start up serial connection
  Serial.begin(9600);

while (!Serial);  // not sure what is this

// for serial monitor?
Serial.println("Input 1 to Turn LED on and 2 to off");
}

void loop()
{
  if (Serial.available())
    {
    int state = Serial.parseInt();
    if (state == 1)
      {
      digitalWrite(13, LOW);
      Serial.println("Command completed LED 13 turned OFF");
      }
    if (state == 2)
      {
      digitalWrite(13, HIGH);
      Serial.println("Command completed LED 13 turned ON");
      }
    if (state == 3)
      {
      digitalWrite(3, LOW);
      Serial.println("Command completed LED 3 turned OFF");
      }
    if (state == 4)
      {
      digitalWrite(3, HIGH);
      Serial.println("Command completed LED 3 turned ON");
      }
    if (state == 5)
      {
      digitalWrite(4, LOW);
      Serial.println("Command completed LED 4 turned OFF");
      }
    if (state == 6)
      {
      digitalWrite(4, HIGH);
      Serial.println("Command completed LED 4 turned ON");
      }
    if (state == 7)
      {
      digitalWrite(5, LOW);
      Serial.println("Command completed LED 5 turned OFF");
      }
    if (state == 8)
      {
      digitalWrite(5, HIGH);
      Serial.println("Command completed LED 5 turned ON");
      }
    if (state == 9)
      {
      digitalWrite(6, LOW);
      Serial.println("Command completed LED 6 turned OFF");
      }
    if (state == 10)
      {
      digitalWrite(6, HIGH);
      Serial.println("Command completed LED 6 turned ON");
      }
    }
}



unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Menus, synaser;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button10: TButton;
    Button11: TButton;
    Button12: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    Button8: TButton;
    Button9: TButton;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    procedure Button10Click(Sender: TObject);
    procedure Button11Click(Sender: TObject);
    procedure Button12Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
    procedure Button9Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  ser: TBlockSerial;
   a: integer;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  ser.SendString('1'); // button 1 should have 'off' here
end;

procedure TForm1.Button10Click(Sender: TObject);
begin
  ser.SendString('10'); // button 10 should have 'on' here
end;

procedure TForm1.Button11Click(Sender: TObject);
begin
  ser.SendString('11'); // button 11 should have 'off' here
end;

procedure TForm1.Button12Click(Sender: TObject);
begin
  ser.SendString('12'); // button 12 should have 'on' here
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ser.SendString('2'); // button 2 should have 'on' here
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  ser.SendString('3'); // button 3 should have 'off' here
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  ser.SendString('4'); // button 4 should have 'on' here
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
  ser.SendString('5'); // button 5 should have 'off' here
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
  ser.SendString('6'); // button 4 should have 'on' here
end;

procedure TForm1.Button7Click(Sender: TObject);
begin
  ser.SendString('7'); // button 7 should have 'on' here
end;

procedure TForm1.Button8Click(Sender: TObject);
begin
  ser.SendString('8'); // button 8 should have 'on' here
end;

procedure TForm1.Button9Click(Sender: TObject);
begin
  ser.SendString('9'); // button 9 should have 'on' here
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ser := TBlockSerial.Create;
  Sleep(25); //250
  ser.Connect('COM5'); // write here Arduino COM port number (on linux it's something like '/dev/ttyUSB0')
  Sleep(25);  //250
  ser.Config(9600, 8, 'N', SB1, False, False);
  ser.RTS := false; // comment this if needed
  ser.DTR := false; // comment this if needed
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ser.free;
end;

end.

nouzi

  • Sr. Member
  • ****
  • Posts: 298
Re: PC to RS485 to Arduino
« Reply #22 on: November 21, 2020, 11:24:31 am »
@microguy
#1 first you can replace code c with pascal code on arduino use cross-compiler  to avr
#2 optimaz code use sender and tag or caption
My English is  bad
Lazarus last version free pascal last version
Lazarus trunk  free pascal trunk 
System : Linux mint  64bit  Windows 7 64bit

microguy

  • New Member
  • *
  • Posts: 49
Re: PC to RS485 to Arduino
« Reply #23 on: November 23, 2020, 04:08:48 am »
@ Nouzi
I don't understand what you do you mean on #1 and #2. Can you give me more explanation?

Can someone give me an example code of how to add second Arduino and code for it?



 

TinyPortal © 2005-2018