Help with Arduino To Arduino Communication

Control Boards, Controllers, Tethers, Ect.
Post Reply
mjp
Posts: 6
Joined: Feb 13th, 2012, 11:42 pm

Help with Arduino To Arduino Communication

Post by mjp »

I have been working on an Arduino control system. I am having trouble understanding the communication programing. I would like to have one Arduino at the controls and another on the ROV. The control one would take all the control signals in and send them to the Arduino on the ROV and that one would actually control the hardware.

Any help with this would be great.
derelicte
Posts: 292
Joined: Aug 1st, 2011, 3:08 pm

Re: Help with Arduino To Arduino Communication

Post by derelicte »

are you using serial between the arduinos?

There are a few ready to use messaging libraries for the arduino in the playground. I'd suggest starting with one of those as it should have all the parsing code done for you.

http://arduino.cc/playground/Main/Inter ... munication
mjp
Posts: 6
Joined: Feb 13th, 2012, 11:42 pm

Re: Help with Arduino To Arduino Communication

Post by mjp »

I would like basically send all the commands to the second arduino on the rov. I just want to duplicate what would happen if i was using a single board but at a remote location. Does any one know if this is possible?
derelicte
Posts: 292
Joined: Aug 1st, 2011, 3:08 pm

Re: Help with Arduino To Arduino Communication

Post by derelicte »

yes.
mjp
Posts: 6
Joined: Feb 13th, 2012, 11:42 pm

Re: Help with Arduino To Arduino Communication

Post by mjp »

does anyone have any information about sending commands to the second arduino?
shaneb24
Posts: 61
Joined: Nov 22nd, 2010, 12:55 pm

Re: Help with Arduino To Arduino Communication

Post by shaneb24 »

ive bean looking in to this heres what i found.

Code: Select all

//***************************************
// ROV Surface unit  v 0.1              *
// Arduino-based ROV telemetry receiver *
//                                      *
//***************************************

#include <NewSoftSerial.h>      //Need soft UART for serial display

#define NULL_PIN  5             //Software UART input pin (not used)
#define DISPLAY_PIN  6          //Software UART output pin (to serial display)

byte incomingByte;
byte headingByte;
byte depthByte;

NewSoftSerial Display_UART(NULL_PIN,DISPLAY_PIN, true); // Input not used; output to serial LCD display RX pin
                                                        // NB: The serial LCD I used (an old one) requires inverted logic. If yours does not, omit ", true" from the line above.
void setup()
{
  Display_UART.begin(9600);
  delay (500);
  Serial.begin(9600);
  delay (500);
}

void loop()
{
  while (Serial.available() > 3)            //Need at least 3 bytes for one frame of telemetry data
  {
    incomingByte = Serial.read();
    
    if (incomingByte == '\r')               //Start of data frame?
    {
      headingByte = Serial.read();
      depthByte = Serial.read(); 
      
      Display_UART.print (254,BYTE);        //Clear LCD screen NOTE: You will need to adjust this line of code to whatever's needed to clear the screen of the LCD you use
      Display_UART.print (1,BYTE);

      Display_UART.print ("  H: ");
      Display_UART.print ((headingByte * 2), DEC);
      
      Display_UART.print ("  D: ");
      Display_UART.print (depthByte, DEC);
      
      delay(250);                            //Show the data on the LCD screen for long enough to see
      Serial.flush();                        //Get rid of any old data that came in while showing last set
    }
  }
}

Code: Select all

/*
 * ROV in-sub unit version 0.1
 * June 2011
 */

// This is the code that runs on the Arduino Pro Mini housed within the ROV itself. It serves two functions:
// 1. It received the PPM signal sent down from the surface unit, mixes two of the channels and sends the appropriate
//    PWM signals to the motor controllers ("electronic speed controllers" or ESCs) and camera-tilt servo.
//
// 2. It interfaces with the digital compass and takes voltage measurements of the output of the pressure sensor. These
//    sensor measurements are then put into a three-byte package (a depth byte, a heading byte, and a carriage return),
//    which is sent to the surface for display. That allows 1-foot depth resolution, and 2-degree heading resolution,
//    which is more than sufficient for this application.
//
// The low-level code used to interface the HMC6352 digital compass is courtesy of Lars Schumann. See http://make.larsi.org/electronics/HMC6352/
//
#include <Servo.h>
#include <Wire.h>

#define channumber 4            //Set to # of channels on RC transmitter being used
                                //This code assumes channel 0 is "elevator" (fwd and rev on right stick)
                                //                  channel 1 is "ailerons" (right and left on right stick)
                                //                  channel 2 is "throttle" (right and left on left stick)
                                //                  channel 3 is "rudder" (fwd and rev on left stick)
                                //You will have to modify "value[x]" accordingly in the code if your radio has different channel assignments
                                //On my setup, channel 0 and 1 are used to control the left and right thrusters (by mixing the channels),
                                //I used channel 2 (throttle) for the middle (up/down) thruster and channel 3 (rudder) to control the camera tilt.

#define neutralPW  1100         //Neutral pulse width from radio (microseconds); measure the PPM signal from your RC radio on an oscilloscope and adjust value to match
#define minPW 600               //Minimum pulse width from radio; measure PPM from your RC radio and adjust value to match
#define maxPW 1600              //Maximum pulse width from radio; measure PPM from your RC radio and adjust value to match
#define PPM_PIN 12              //Send the PPM signal to this pin on the Arduino
#define RIGHT_THRUSTER_PIN 6    //PWM output to ESC controlling right thruster
#define LEFT_THRUSTER_PIN 8     //PWM output to ESC controlling left thruster
#define CENTER_THRUSTER_PIN 7   //PWM output to ESC controlling center thruster
#define CAMERA_SERVO_PIN 13     //PWM output to control camera-tilt servo

long value[channumber];         //Channel pulse widths from PPM signal (channels 0 to 3)
long old_camera_servo_value;    //Needed to prevent camera servo from jiggling
long camera_deadband = 25;
int right_thruster_pw;          //Output to right-thruster ESC
int left_thruster_pw;           //Output to left-thruster ESC
int center_thruster_pw;         //Output to center-thruster ESC
int camera_servo_pw;            //Output to camera servo

Servo right_thruster;           //Servo object to control the right thruster
Servo left_thruster;            //Servo object to control the left thruster
Servo center_thruster;          //Servo object to control the center thruster
Servo camera_servo;             //Servo object to control the camera-tilt servo

int HMC6352Address = 0x42;      //Digital compass
int slaveAddress;               //Calculated in Setup

byte headingData[2];
int i;
int j;
int x;
int headingValue;
int temp;
int depth;
int pressureZero;                          //Pressure sensor output at surface
int counter = 0;

void setup()
{
// Serial.begin(9600);                     //Needed only for testing
// Serial.println ("Initializing");
  
  //Stuff for servo/esc control

  pinMode(PPM_PIN, INPUT);                 //Pin for PPM signal needs to be an input
  pinMode(RIGHT_THRUSTER_PIN, INPUT);      //Pin for PPM signal needs to be an output
  pinMode(LEFT_THRUSTER_PIN, INPUT);       //Pin for PPM signal needs to be an output
  pinMode(CENTER_THRUSTER_PIN, INPUT);     //Pin for PPM signal needs to be an output
  pinMode(CAMERA_SERVO_PIN, INPUT);        //Pin for PPM signal needs to be an output
  
  right_thruster.attach(RIGHT_THRUSTER_PIN);    //PWM signal for right thruster on Pin 6
  left_thruster.attach(LEFT_THRUSTER_PIN);      //PWM signal for right thruster on Pin 7
  center_thruster.attach(CENTER_THRUSTER_PIN);  //PWM signal for right thruster on Pin 8
  camera_servo.attach(CAMERA_SERVO_PIN);        //PWM signal for camera-tilt servo on Pin 9
  
  // Stuff for HMC6352 digital compass
  // Here we shift the device's documented slave address (0x42) 1 bit right

  // This compensates for how the TWI library only wants the
  // 7 most significant bits (with the high bit padded with 0)
  
  slaveAddress = HMC6352Address >> 1;  
  
  // This results in 0x21 as the address to pass to TWI

  Wire.begin();
  
  pressureZero = analogRead(0);                   //Pressure sensor output at surface
 
}

void loop()
{
  //Zero the value[x] array
  for(x=0; x<=channumber-1; x++)            
  {
    value[x] = 0; 
  }
  
  for (j=0; j<5; j++)                               //Read PPM frames 5 times and average
  {  
    while(pulseIn(PPM_PIN, LOW) < 5000){}           //Wait for the beginning of the frame
  
    for(x=0; x<=channumber-1; x++)                  //Loop to store all the channel position
    {
      value[x] = value[x] + pulseIn(PPM_PIN, LOW);  //Accumulate values for averaging
    }
  }
  
  for(x=0; x<=channumber-1; x++)                    //Divide to get average value
  {
    value[x] = value[x] / 5;
  }
  
  if (abs(value[2] - old_camera_servo_value) < camera_deadband)  //To prevent camera from jiggling
  {                                                              // Don't move unless target is outside deadband
    value[2] = old_camera_servo_value;
  }
  else
  {
    old_camera_servo_value = value[2];
  }

  Mix ();                                                 //Mix channels 0 and 1 so as to control left and right thrusters properly

  right_thruster.writeMicroseconds(value[0] + 400);       //Output for ESC
  left_thruster.writeMicroseconds(value[1] + 400);        //Output for ESC
  center_thruster.writeMicroseconds(value[3] + 400);      //Output for ESC controlling center thruster (use rudder stick to control)
  camera_servo.writeMicroseconds(value[2] + 400);         //Output for camera-tilt servo (use throttle stick to control)
  
  GetHeading ();                                          //Determine heading
  GetDepth ();                                            //Determine depth
  Send_Data_Topside();                                    //Send compass heading and pressure depth data to the surface (each 1/4 second)
} 

//Subroutines
//
//This routine mixes the aileron and elevator channels so that pushing the right stick forward powers both right and
//left thrusters, making the ROV go forward. Pushing the right stick to one side, makes the ROV turn.
//Note that you have to check that the mixed signals don't exceed normal bounds of PWM width when the stick is pushed
//both forward (or revese) and to one side.
void Mix ()
{
  int right_out;
  int left_out;
  
  right_out = (value[0] + (value[1] - neutralPW));

  if (right_out > maxPW)
  {
    right_out = maxPW;
  }

  if (right_out < minPW)
  {
    right_out = minPW;
  }

  left_out = (value[0] - (value[1] - neutralPW));
  
  if (left_out > maxPW)
  {
    left_out = maxPW;
  }

  if (left_out < minPW)
  {
    left_out = minPW;
  }

  value[0] = right_out;
  value[1] = left_out;
}

void GetHeading ()
{
  // Send an "A" command to the HMC6352
  Wire.beginTransmission(slaveAddress);
  Wire.send("A");              // The "Get Data" command
  Wire.endTransmission();
  delay(10);
  // The HMC6352 needs at least a 70us (microsecond) delay
  // after this command.  Using 10ms just makes it safe
  // Read the 2 heading bytes, MSB first
  // The resulting 16bit word is the compass heading in 10th's of a degree
  // For example: a heading of 1345 would be 134.5 degrees

  Wire.requestFrom(slaveAddress, 2);        // Request the 2 byte heading (MSB comes first

  i = 0;

  while(Wire.available() && i < 2)
  {
    headingData[i] = Wire.receive();
    i++;
  }
  headingValue = headingData[0]*256 + headingData[1];  // Put the MSB and LSB together
}

void GetDepth()
{
  depth = analogRead(0) - pressureZero;                //Read pressure sensor and substract zero value
  depth = (int)(depth * 0.353);                        //Convert to feet of depth (from linear regression on sensor)


}

 
void Send_Data_Topside ()
{
  byte heading_byte;
  byte depth_byte;
  
  heading_byte = lowByte(headingValue/20);              //Maps 0 to 360 degrees to values in the range 0 to 180 (so it can fit in one byte)
  
  if (depth < 0)
  {
    depth_byte = 0;
  }
  else
  {
    depth_byte =  lowByte(depth);
  }

  Serial.print (heading_byte);
  Serial.print (depth_byte);
  Serial.print ('\r');                       //Print CR (without any LF)
}

I did not program any of this.


ive bean looking at this. id use the max490 and the lcd but i want them to talk to a ps2 controller at top side. the Arduino at rov id want pwm and IO for water leak, relays and speed controllers
Attachments
ROV_surface_unit.pdf
(13.54 KiB) Downloaded 602 times
ROV_electronics.pdf
(14.62 KiB) Downloaded 588 times
Last edited by shaneb24 on Feb 15th, 2012, 2:05 pm, edited 1 time in total.
derelicte
Posts: 292
Joined: Aug 1st, 2011, 3:08 pm

Re: Help with Arduino To Arduino Communication

Post by derelicte »

Something like that would work.

You should wrap your code with the

Code: Select all

 tag. it makes it easier to read.
Post Reply