Show Posts
Pages: 1 2 [3] 4 5
31  Using Arduino / Networking, Protocols, and Devices / Still needing help with RS485 on: January 31, 2013, 01:10:51 pm
With Nicks Gammons  RS485 Master code listed below (all be it played with by me)
can someone please tell me how i can get to serial.print the received slave message from the master.
http://www.gammon.com.au/forum/?id=11428  Nick project is here.

it obviously receives something as the Led on pin d13 does not light up indicating that there is no error and that the message was acknowledged.

I would like the slave to pass messages back when polled and i believe this is already in place, i would like to be able to have several bytes sent in the return message which can be written to variable so that i can output them to the Host (pc connected to master module).
thanks
J.
Code:
#include "WConstants.h"
#include <NewSoftSerial.h>
#include "RS485_protocol.h"

NewSoftSerial rs485 (2, 3);  // receive pin, transmit pin
const byte ENABLE_PIN = 4;
int channel = 0;
int data=0;
const byte LED_PIN = 13;
int incomingByte=0; // for incoming serial data
int thousands=0; int hundreds =0; int tens =0; int ones=0;
int inByte=0;
// callback routines
 
void fWrite (const byte what)
  {
  rs485.print (what); 
  }
 
int fAvailable ()
  {
  return rs485.available (); 
  }

int fRead ()
  {
  return rs485.read (); 
  }

void setup()
{
  rs485.begin (28800);
   Serial.begin(9600);
  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable
  pinMode (LED_PIN, OUTPUT);  // built-in LED
}  // end of setup
 
byte old_level = 0;

void loop()
{

  // read potentiometer

 // byte level = analogRead (0) / 4;// commented out as it is now variable being written
  byte level = (incomingByte);
  // Serial.print(level);// print to serial monitor - for testing only
   
   if (Serial.available() > 0) {       //read value from host PC
    hostprotocol();
   }
  // no change? forget it
  if (level == old_level)
    return;
     
  // assemble message
  byte msg [] = {
     1,    // device 1
     2,    // turn light on
     level // to what level
  };

  // send to slave 
  digitalWrite (ENABLE_PIN, HIGH);  // enable sending
  sendMsg (fWrite, msg, sizeof msg);
  delayMicroseconds (660);
  digitalWrite (ENABLE_PIN, LOW);  // disable sending
 
// receive response 
  byte buf [20];
  byte received = recvMsg (fAvailable, fRead, buf, sizeof buf);
 
  digitalWrite (LED_PIN, received == 0);  // turn on LED if error 
 
  // only send once per successful change
  if (received)
{
    if (buf [0] != channel)
      return;  // not my device
     
    if (buf [1] != 2)
      return;  // unknown command
   
byte msg [] = {
       0,  // device 0 (master)
       data,  // turn light on command received
       //data

};
 
    old_level = level;

}

}  // end of loop

void hostprotocol()      //Serial commands received from host
{
  inByte = Serial.read();
    switch (inByte)
    {
     
 case 79: //O  out
 
        DigitalOut();
   break;
 
  }
}
void DigitalOut() {
   
 // send data only when you receive data:
Serial.print("Digital OK");
 
 // only if there are bytes in the serial buffer execute the following code
  if(Serial.available()) {
   
     //keep reading and printing from serial untill there are bytes in the serial buffer
     //while (Serial.available()>0){
       if (Serial.available()>2){ // got 3 characters
       
// assume comes in as hundreds, tens, ones
hundreds = Serial.read() - 0x30;  // read the byte & convert from ASCII to a number
tens = Serial.read() - 0x30;
ones = Serial.read() - 0x30;

// now make into a digit
incomingByte =  hundreds*100 + tens*10 + ones;
     
 }
 Serial.print(incomingByte);
    }
 
//int value = (incomingByte);
 }

32  Using Arduino / Programming Questions / Re: help with String manipulation on: January 31, 2013, 06:47:00 am
Thanks for the replies,
i have taken onboard all of your ideas and given them all a try.

As Nick has noticed, i still working on a RS485/modbus communication project

the command was going to be the device ID xxx - a function "o" being Output (Digital) and yyy being the value/byte sent to the slave device to drive the digital values which are Bit weighted.

This was going to be the structure and would be similar format for all commands from a host PC to the RS485 master device.
the numbering format was to be 3 characters no matter what and the function would always be a character.

From Pauls earlier post the comma delimited suggestion appears to be the most simplistic and straight forward method.

It should now allow me to to create address IDs of any size - say 4000      The function command could be similar, i will probablly keep to values in 1 byte ie, 0 to 255 as Nick Gammons RS485 comms example uses Bytes in the message transfer.

Its a steep learning curve, thank you all for your assistance, much appreciated
33  Using Arduino / Networking, Protocols, and Devices / Re: Working RS485 sketches wanted on: January 30, 2013, 05:58:23 pm
With Nicks code above (all be it played with by me)
can someone please tell me how i can get to serial.print the received slave message from the master.
it obviously receives somthing as the Led on pin d13 does not light up indicating that there is no error and that the messege was acknowledged.

I would like the slave to pass messages back when polled and i belive this is already in place, i would like to be able to have several bytes sent in the return message which can be written to variable so that i can output them to the Host (pc connected to master module).
thanks
J.
34  Using Arduino / Programming Questions / Re: help with String manipulation on: January 27, 2013, 01:41:33 pm
Yes i understand what you are saying but unfortunately i dont have delimiting characters
 the format is 255O255|the part of the code which is handling the parsing does not see the end character "|" which has already been stripped.
i need to be able to use the character position instead.
the examples dont offer any suggestion on how to do this.

as mentioned above i could in VB.

I am currently going back over the code and seeing if i can adopt Pauls suggestion.

thanks for the help
J.
35  Using Arduino / Programming Questions / Re: Help with coding LEDs with Shift Register on: January 27, 2013, 01:28:58 pm
I think you may be asking about somthing i worked on recently
i wanted to get bit weighting so i could write a byte to the arduino and use it to switch individual outputs :-
(was based on an arduino  Mega)

initiate the the required pins
Code:
int ledPin = 52;
int ledPin1 = 50;
int ledPin2 = 48;
int ledPin3 = 46;
int ledPin4 = 44;
int ledPin5 = 42;
int ledPin6 = 40;
int ledPin7 = 38;

in  setup
set pins as outputs
Code:
pinMode(ledPin, OUTPUT);  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin2, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin3, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin4, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin5, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin6, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin7, OUTPUT); // initialize the LED pin as an output:
and this was in the loop
Code:
// only if there are bytes in the serial buffer execute the following code
  if(Serial.available()) {
  
     //keep reading and printing from serial untill there are bytes in the serial buffer
     //while (Serial.available()>0){
       if (Serial.available()>2){ // got 3 characters
        
// assume comes in as hundreds, tens, ones
hundreds = Serial.read() - 0x30;  // read the byte & convert from ASCII to a number
tens = Serial.read() - 0x30;
ones = Serial.read() - 0x30;

// now make into a digit
incomingByte =  hundreds*100 + tens*10 + ones;
    
 }
 Serial.print(incomingByte);
    }
 
int value = (incomingByte);
 
   digitalWrite(ledPin, (value >> 0 )% 2);// LSB
   digitalWrite(ledPin1, (value >> 1)% 2);
   digitalWrite(ledPin2, (value >> 2)% 2);
   digitalWrite(ledPin3, (value >> 3)% 2);
   digitalWrite(ledPin4, (value >> 4) % 2);
   digitalWrite(ledPin5, (value >> 5) % 2);
   digitalWrite(ledPin6, (value >> 6) % 2);
   digitalWrite(ledPin7, (value >> 7) % 2); // MSB

I sent a value from 0-255 via the serial port which switched individual pin outputs.
the value was sent in the format 000 ~255 (alway 3 characters)

Hope this was helpful
36  Using Arduino / Programming Questions / Re: Temeratures control with outputs on: January 27, 2013, 01:17:44 pm
Look up arduino reflow oven.
there are loads of people building PID controlled ovens for SMD electronics soldering and other are using the arduino to control cooking.
the same principle can be adopted for heating liquids.
you will need to download the PID library, but any of the available sketches will provide what you desire.

im currently working on a test oven at work which is using a sketch i found through adafruits site.

you will need heavy relays/SCRs or even contactors to control your heating elements, look at connecting relays to arduinos.
you might want to consider stirring the liquid to get an even heat, this is normal in industrial applications

the rest should be childs play
37  Using Arduino / Programming Questions / Re: help with String manipulation on: January 27, 2013, 12:45:48 pm
Hi Zoomkat,
i saw the information you pointed out,
unfortunately i couldnt find an example which would simply strip characters from a string between linits.
could you provide me with a direct link to the example
cheers
Jason
38  Using Arduino / Programming Questions / Re: help with String manipulation on: January 27, 2013, 12:22:03 pm
Hi Paul,
You are absolutely right.
i was going down the road of manipulating the code i had already.
comma delimited does make a lot of sense.

It looks like im going back to rewriting a hole heap of code.

I was hoping that there would be a straight forward solution like SlaveID=mid(cstring,0,3) - good old VB

ahh well back to the drawing board
cheers
J.
39  Using Arduino / Programming Questions / Re: help with String manipulation on: January 27, 2013, 11:58:04 am
Ok
I have attached my code, so hopefully you can see what im trying to acheive.

I have been working on getting an RS485 modbus link set up and this code will be used by the Host PC to communicate with the master module

Input string should arrive in the format of 255O255|
the first 3 characters are the Slave device address
Capital Letter "O" designates an output function
the remainder is the digital value to be transmitted over an RS485 Link
followed by a termination character "|"
used to generate a message of ID, Function, value

The code im using was plagerised from a stepper motor program, I liked the way in which it analyses the serial input.
I just want to increase the number of Slave IDs

The code is working

Code:
#define USB_SERIAL
#define ON 1
#define OFF 0


#include <stdio.h> // for function sprintf


// Conditional start
int Startup = 0;
int Run = 0;
int SlaveID = 0;
byte DigitalVal =0;

#if defined(USB_SERIAL)
 #include <ctype.h>     //needed for function 'toupper'
 #include <string.h>    //needed for 'strcmp' and 'strcat'
#endif

int test = ON; // E for Echo                 //test facility which can be enabled/diabled via serial port command
                                  //presently this only echoes commands back to serial port  --  possibly useful during development of PC based driver programs
int hundreds,tens,ones;

 #if defined(USB_SERIAL)
 int analyse_command_string(char cstring[]);
 char *stripallspaces( char *s );

 //set up program information
 char progname[60] = "Winder Control v";  //this info will be echoed to the serial port on startup or reboot of the Arduino
 char progversion[] ="1";
 char commandstring[130] = "";     //serial input string buffer
#endif



void setup()

  #if defined(USB_SERIAL)

  //set up serial port
  Serial.begin(9600); 
#endif 
}


void loop()
{
  int c, i;
   int static n = 0; // NOTE: THIS VARIABLE MUST BE DECLARED AS STATIC
   
// ----------------------------- READ SERIAL INPUT STRING -------------------------------------------------
#if defined(USB_SERIAL)

     //SET FOR CONTROL VIA USB_SERIAL PORT
     //
     if (Serial.available() > 0)  //ie charater(s) in input buffer
       {
       commandstring[n] = Serial.read(); n++;   
       if (commandstring[n-1] == '|') //ie character is '|' (end of command marker)
          {
          commandstring[n]='\0';  //terminate string and reset counter ready for next string
          n = 0;
       
          //if test mode enabled, echo string back to serial port -- could be useful for development of driver programs
          if (test == ON) {Serial.println(commandstring); Serial.print("\n");}
             
          //analyse command string and place info into motor1 or motor2 'struct's
          if(analyse_command_string(commandstring) == -1) n = 0;
       } 
      } //END OF USB_SERIAL PORT SECTION
#endif

}
// -------------------------- SERIAL COMMANDS ------------------------------------------

#if defined(USB_SERIAL)
//CODE BELOW HERE NEEDED ONLY FOR CONTROL VIA USB_SERIAL PORT
int analyse_command_string(char cstring[])
{
 
   
  int x = 0;//

   char s[20];
   
   //Strip all spaces that might be in the command string
   stripallspaces(cstring);
   
    //Look for Start winder enable/disable
   if (toupper(cstring[0]) == 'P')
      {
      s[0] = cstring[1]; s[1] = '\0';
      if(strcmp(s,"1") == 0) Startup = 1;
      if(strcmp(s,"0") == 0) Startup = 0;
     // Serial.println("CF1!");
      return 0;
      }
   
    //Look for winder run/stop command
   if (toupper(cstring[0]) == 'R')
      {
      s[0] = cstring[1]; s[1] = '\0';
      if(strcmp(s,"1") == 0) Run = 1;
      if(strcmp(s,"0") == 0) Run = 0;
      Serial.println("OK!");
      return 0;
      }
     

   //Look for test enable/disable
   
   if (toupper(cstring[0]) == 'E') //E for Echo was T for Test - all test statements have been scripted out
      {
     s[0] = cstring[1]; s[1] = '\0';
     if(strcmp(s,"+") == 0) test = ON;
      if(strcmp(s,"0") == 0) test = OFF;
    return 0;
     }
     
//======================================================================================================================
//Input string should arrive in the format of 255O255|
// the first 3 characters are the Slave device address
// Capital Letter "O" designates an output function
// the remainder is the digital value to be transmitted over an RS485 Link
// followed by a termination character "|"
// used to generate a message of ID, Function, value



 //All other commands must begin with a SlaveID number/character
   //Get SlaveID
   s[0] = cstring[0]; s[1] = '\0'; SlaveID = atoi(s);
   
  //The second character defines the parameter that is to be set
  //** i want this to be the fourth as i want 255 addresses and not just 9.
 
   //Ensure that this is in upper case
   cstring[1] = toupper(cstring[1]);  //this is the function character
       
   //Now search string for the function parameters
 
 if (cstring[1] == 'O') //Send DigitalOutput value
      {
      x = 0; while(cstring[2+x] !='|'){s[x] = cstring[2+x]; x++;}
      s[x] = '\0';
      DigitalVal = (unsigned long)atol(s);  //note use of 'long int' here
      //if (motorID == 1) motor1.interval = interval; else motor2.interval = interval;
     Serial.print(SlaveID);
     Serial.print(" ");
     Serial.print(DigitalVal);
      return 0;
      }
   
 
//=====================================================================================================================
     
   //Should not get to here so print error
   Serial.print("ERROR: Unrecognised command\n"); return -1;
}


char *stripallspaces( char *s )
{
   //Strips ALL spaces from string 's'
   char s1[256];
   int c0 = 0;
   int c1 = 0;
   while ( s[c0] != '\0' )
       {
       while( s[c0] == ' ' ) c0++;
           s1[c1] = s[c0];
           c0++;
           c1++;
       }
   s1[c1] = '\0';
   strcpy( s, s1 );
   return &s[0];
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
#endif    // END OF CODE NEEDED FOR CONTROL VIA USB_SERIAL PORT
40  Using Arduino / Programming Questions / Re: help with String manipulation on: January 27, 2013, 09:51:01 am
I have worked out that this code simply tests the first character and stores it,

so back to my question
how can i filter a string to give me the first 3 characters so that i can store it,
i want to capture a 3 digit value i. 255.
in VB6 i can use the mid or instring command and get the characters i want
how is this acheived with c and the arduino code.

I have looked at the tutorials and string examples but i have not found one that will filter characters out of a string

please help
J.
41  Using Arduino / Programming Questions / help with String manipulation on: January 27, 2013, 08:25:27 am
Need some help understanding this line of code
Code:
s[0] = cstring[0]; s[1] = '\0'; SlaveID = (unsigned long)atoi(s);

Its purpose is to parse a string input and store the value in SlaveID (in this case the first character from a serial input string)

I want to be able to use 3 characters ie. 255.
the code above only shows the first character

how can i manipulate it so i cand display the first 3 characters of a string
in essence how does the line above work
42  Using Arduino / Networking, Protocols, and Devices / Re: Working RS485 sketches wanted on: January 26, 2013, 12:27:37 pm
2nd part

The modified RS485 slave code is as follows

Code:

#include "WConstants.h"
#include <NewSoftSerial.h>
#include "RS485_protocol.h"

NewSoftSerial rs485 (2, 3);  // receive pin, transmit pin
const byte ENABLE_PIN = 4;
int channel = 1;// Device ID

int Inputvalue =0; // Input value from Master

int ledPin = 12;// digital bit weighted outputs
int ledPin1 = 11;
int ledPin2 = 10;
int ledPin3 = 9;
int ledPin4 = 8;
int ledPin5 = 7;
int ledPin6 = 6;
int ledPin7 = 5;


void fWrite (const byte what)
  {
  rs485.print (what); 
  }
 
int fAvailable ()
  {
  return rs485.available (); 
  }

int fRead ()
  {
  return rs485.read (); 
  }
 
void setup()
{
  rs485.begin (28800);
  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable
  //Bit weighted gigital outputs
  pinMode(ledPin, OUTPUT);  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin2, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin3, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin4, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin5, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin6, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin7, OUTPUT); // initialize the LED pin as an output:
}

void loop()
{
  byte buf [20];
 
  byte received = recvMsg (fAvailable, fRead, buf, sizeof (buf) - 1);
 
  if (received)
    {
    if (buf [0] != channel)
      return;  // not my device
     
    if (buf [1] != 2)
      return;  // unknown command
   
    byte msg [] = {
       0,  // device 0 (master)
       3,  // turn light on command received
    };
   
    delay (5);  // give the master a moment to prepare to receive
    digitalWrite (ENABLE_PIN, HIGH);  // enable sending
    sendMsg (fWrite, msg, sizeof msg);
    digitalWrite (ENABLE_PIN, LOW);  // disable sending
   
    //analogWrite (11, buf [2]);  // set light level AS WAS  JT

    Inputvalue =buf [2];// write register value to a variable JT

   // digital bit weighted outputs
   digitalWrite(ledPin, (Inputvalue >> 0 )% 2);// LSB
   digitalWrite(ledPin1, (Inputvalue >> 1)% 2);
   digitalWrite(ledPin2, (Inputvalue >> 2)% 2);
   digitalWrite(ledPin3, (Inputvalue >> 3)% 2);
   digitalWrite(ledPin4, (Inputvalue >> 4) % 2);
   digitalWrite(ledPin5, (Inputvalue >> 5) % 2);
   digitalWrite(ledPin6, (Inputvalue >> 6) % 2);
   digitalWrite(ledPin7, (Inputvalue >> 7) % 2); // MSB
   
   }  // end if something received
   
}  // end of loop
A Picture of the PCB layout for the MAX485 and a drawing showing the various connections will be provided later.





What has been achieved?

You can now drive 8 relays for example which are 1000m away from your PC over 2 wires (twisted pair TWP) a line resistor of 120 ohms will be needed between the A/B wire connections on both ends of the wire link.  Look at LVR.com where Jan Alexson explains serial communication and RS485 at great depth- especially calculating the line resistor for a given wire link/distance
(The remote board will obviously require its own power)

Issues
Data type is wrong for data value being transmitted; currently it’s a byte where the input from the host PC is a formatted string/decimal value.
Where the host PC sends O237 the slave works but when the value is less than 100 the slave doesn’t change.
In the slave code the value is parsed to give 100s, 10s and units, it is not needed the value should be able to be used directly.  This change has not been implemented yet.
43  Using Arduino / Networking, Protocols, and Devices / Re: Working RS485 sketches wanted on: January 26, 2013, 12:26:57 pm
Thanks Chaps,
This is how far i have managed to get
Basic RS485 Master/Slave example from Nick Gammons code.
The changes made are the introduction of a bit weighted digital output on the slave and a PC host serial connection to the master module.

The design idea is to be able to use a host PC with a USB connection to a master module to control several slaves for use in hobby based micro controlled logical interface, this will differ from a programmable logic controller PLC as the code will be written to the device once and then the multiple devices will have various fixed functions which will only respond when controlled from the master commands.

Industrial systems would be like the Wago or an intelligent relay for example.
this system/project will be perfect for home automation, model railways, flight sims, robotic control to name but a few uses.

C# is not my preferred programming language so if its crap code, get over it

You need to do the following prerequisites before you can use this code.

I used Nick Gammons schematic for setting up my RS485 link
The code was loaded onto two separate Arduino Uno’s – master on one slave on the other

The Software serial version of the Arduino RS485 code was used – this leaves the USB serial link free for programming and interfacing with the devices
Nick code example used an analogue input to generate a value to be transmitted to the slave as a message, I commented this out and set up a variable to hold the incoming value – this value is used to hold the value to be used for driving the digital outputs D5,D6,D7,D8,D9,D10,D11,D12 these outputs are bit weighted, ie
255 smiley-cry 11111111) D5=1,D6=1,D7=1,D8=1,D9=1,D10=1,D11=1,D12=1
000 smiley-cry 00000000) D5=0,D6=01,D7=0,D8=0,D9=0,D10=0,D11=0,D12=0
127 smiley-cry 11111111) D5=1,D6=0,D7=0,D8=0,D9=0,D10=0,D11=0,D12=0
Got it – cool    don’t forget to attach LEDs to the digital outputs (with a load resistor).
D13 was left as an error indication LED
It’s a pain writing to two devices on one machine, remember to change serial port between uploading to devices – two masters or two slaves isn’t a good start, been there.

The initial problems I had using Nicks code was I didn’t read his instruction fully or correctly, sorry Nick. This led to me misunderstanding that using the hardware example was using the same pins as the USB port the second issue was I built the MAX485 physical link and for some reason felt that was it and it should work – I needed an LED on pin D11 of the master and an analogue input A0 on the slave.
Don’t make the same mistakes I made, getting impatient with Angry Mike,PaulS and Nick Gammon is not a good move, im still left out in the dark, sorry guys.

The next stage will be to add more Slave units for analogue input, analogue/PWM output and digital input.
On completion of basic operation, I plan to use the various modbus examples to actually incorporate a proper communication protocol.

Again don’t follow in my footsteps and ask general questions about how to use RS485 for communication, the guys on the forum are unforgiving and will eat you alive, yep we all know there are various communication methods/protocols when using RS485 links – so spell it out.  Thanks to Lefty for intervening and calming the waters.

Ok so once set up
Open the serial monitor tool and send digital values to the master
The format is as follows:
O***  where O is capital letter “O” followed by 0 to 255 formatted to 3 digits, 0 = 000 and 255 = 255
The modified master code is as follows
Code:

#include "WConstants.h"
#include <NewSoftSerial.h>
#include "RS485_protocol.h"

NewSoftSerial rs485 (2, 3);  // receive pin, transmit pin
const byte ENABLE_PIN = 4;
int channel = 0;
int data=0;
const byte LED_PIN = 13;
int incomingByte=0; // for incoming serial data
int thousands=0; int hundreds =0; int tens =0; int ones=0;
int inByte=0;
// callback routines
  
void fWrite (const byte what)
  {
  rs485.print (what);  
  }
  
int fAvailable ()
  {
  return rs485.available ();  
  }

int fRead ()
  {
  return rs485.read ();  
  }

void setup()
{
  rs485.begin (28800);
   Serial.begin(9600);
  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable
  pinMode (LED_PIN, OUTPUT);  // built-in LED
}  // end of setup
  
byte old_level = 0;

void loop()
{

  // read potentiometer

 // byte level = analogRead (0) / 4;// commented out as it is now variable being written
  byte level = (incomingByte);
  // Serial.print(level);// print to serial monitor - for testing only
  
   if (Serial.available() > 0) {       //read value from host PC
    hostprotocol();
   }
  // no change? forget it
  if (level == old_level)
    return;
      
  // assemble message
  byte msg [] = {
     1,    // device 1
     2,    // turn light on
     level // to what level
  };

  // send to slave  
  digitalWrite (ENABLE_PIN, HIGH);  // enable sending
  sendMsg (fWrite, msg, sizeof msg);
  delayMicroseconds (660);
  digitalWrite (ENABLE_PIN, LOW);  // disable sending
  
// receive response  
  byte buf [20];
  byte received = recvMsg (fAvailable, fRead, buf, sizeof buf);
 
  digitalWrite (LED_PIN, received == 0);  // turn on LED if error  
  
  // only send once per successful change
  if (received)
{
    if (buf [0] != channel)
      return;  // not my device
      
    if (buf [1] != 2)
      return;  // unknown command
    
byte msg [] = {
       0,  // device 0 (master)
       data,  // turn light on command received
       //data

};
  
    old_level = level;

}

}  // end of loop

void hostprotocol()      //Serial commands received from host
{
  inByte = Serial.read();
    switch (inByte)
    {
      
 case 79: //O  out
 
        DigitalOut();
   break;
  
  }
}
void DigitalOut() {
    
 // send data only when you receive data:
Serial.print("Digital OK");
  
 // only if there are bytes in the serial buffer execute the following code
  if(Serial.available()) {
  
     //keep reading and printing from serial untill there are bytes in the serial buffer
     //while (Serial.available()>0){
       if (Serial.available()>2){ // got 3 characters
        
// assume comes in as hundreds, tens, ones
hundreds = Serial.read() - 0x30;  // read the byte & convert from ASCII to a number
tens = Serial.read() - 0x30;
ones = Serial.read() - 0x30;

// now make into a digit
incomingByte =  hundreds*100 + tens*10 + ones;
    
 }
 Serial.print(incomingByte);
    }
 
//int value = (incomingByte);
 }


44  Using Arduino / Networking, Protocols, and Devices / Re: Working RS485 sketches wanted on: January 12, 2013, 05:58:00 am
Hi Lefty/Mike
Your help has been really useful.
i am aware from having worked offshore for the last ten years that what i wanted is possible i just needed pointed in the right direction.
i think its peoples lazy description of the communication protocol which has confused me.
we use RS485 links to talk to an array of underwater instruments such as dopler, sonar, altimeter, bathy, profilers etc, many of which are on a RS485 bus called arcnet, believe it or not they all pass data back at very high speeds. Eg, a sonar would be useless if it couldnt return a message showing its signal its returns.  The general description is to call it RS485 instead of actually saying what communication protocol it is using.

*second serial port.
i tried to describe my intention to use both a hardware and software serial link in the master so that i could communicate via a PC to the BUS, i appolegise for any confusion.  I have come to the conclusion im really crap at asking questions, the guys on the forum seem to have dificulty understanding mine.
I do appreciate you are all unpaid for your assistance on the forum and have a life.

I have taken a look at modbus and over the next week or so will have a go at getting it to work for my simple Arduino programable logic controller.

I want to use RS485 because i want communication with devices over a 100m distance.
45  Using Arduino / Networking, Protocols, and Devices / Re: Working RS485 sketches wanted on: January 06, 2013, 03:52:14 pm
i didnt pick up on was the difference between Hardware and Software and how it pertained to my setup.
Ie. if you used the hardware config it was the USB link i was using to upload the sketch etc.

I did discover it had been working all along, I quickly coupled the circuit together and must have skimmed over the part indicating the LED on pin 11. once inserted the Uno pair started working as expected.

I have a couple of quick questions if you don’t mind.
Im not able to find a way of breaking into the code on the master to allow PC interface/interaction, i want to be able to send and receive serial data from the master.

I have added a second serial connection in the code with a 9600 baud rate and it works at sending and receiving from the master whilst its running the 485 link however i don’t quite understand how to write or read data to be used in the 485 message.


The second question is how to understand the slaves return message, are you able to provide an explanation as to how this  is achieved.
as far as i can figure out  there is a return response which the master hears and hold LED on pin13 low unless there is a broken link, corrupted message or i guess a time out.
Pages: 1 2 [3] 4 5