New ROV - The Mimee

What are you working on .... Show off your Rov's Projects here.
a_shorething
Posts: 289
Joined: Sep 10th, 2013, 5:26 pm
Location: New Jersey Shore

Re: New ROV - The Mimee

Post by a_shorething »

Tal wrote:
a_shorething wrote:Lots of really useful information
Thanks so much, a_shorething! I didn't quite realise that once a condition had been met, that it completed the loop. I really am still a beginner :) and your feedback has helped heaps.
Ha ha- you're welcome.

That's true only within a case statement, not for the loop in general.

If you want I can post my actual code (that was just 'pseudo-code' written off the top of my head).

Within a case statement you can basically 'branch' to different options based on a set of conditions and only one of them will be executed (the first one that is true).

Then it continues with the first line of code after your case statement, going through the rest of the loop of the Arduino code.
Tal
Posts: 47
Joined: Feb 7th, 2013, 8:10 pm

Re: New ROV - The Mimee

Post by Tal »

a_shorething wrote:If you want I can post my actual code
Thanks a million. I'm not familiar with the case command, so being able to see it in context would help me heaps. I don't want to over-complicate, but it seems that this would actually be simplifying my code. I'd really appreciate seeing your actual code!

Thanks again :)
a_shorething
Posts: 289
Joined: Sep 10th, 2013, 5:26 pm
Location: New Jersey Shore

Re: New ROV - The Mimee

Post by a_shorething »

Tal wrote:
a_shorething wrote:If you want I can post my actual code
Thanks a million. I'm not familiar with the case command, so being able to see it in context would help me heaps. I don't want to over-complicate, but it seems that this would actually be simplifying my code. I'd really appreciate seeing your actual code!

Thanks again :)
OK, it's on my laptop, I'll post it up later on tonight.

EDIT: Ok here it is:
In Arduino land, a 'case' statement is a 'switch case' statement. So if you look for the word 'switch' you will see what variable is being tested, the 'case' parts that follow it are what it's being evaluated against, the first one that's true will be the code that is used, the rest will be skipped. Each case has a 'break' and then the end of the switch is indicated by a close curly bracket: > }

- sorry, there is a lot going on here, but this is for my XBOX pass-thru program so it accepts code for up to 4 XBOX controllers, and then parses out which button is sent, then determines what to do with each one. I'm not using any procedures as you can see, which would make it more readable and probably less confusing, but it's all there, you can see some nested 'case' statements in there, the first one is for the controller number and the next one is for the button number. Beyond that I plan to add specific cases for combinations of buttons. This one is my initial test to send signals through to my motor shield from Adafruit. I plan to change this up a bit when I get the PWM driven boards that Colm found and posted in his Irish ROV thread.

There is also some code in there for a thermocouple board I'm using to check temp and I plan to send that back topside or put it into some OSD stuff.

, um, there's also some code in there to send feedback back to the software over the serial link for the 'force feedback' of the XBOX controller. I thought it was cool anyway... :)




/* Built on Serial Event example, and AF motor example from Adafruit

When new serial data arrives, this sketch adds it to a String.
When a newline is received, the loop prints the string and
clears it.

A good test for this is to try it with a GPS receiver
that sends out NMEA 0183 sentences.

Created 9 May 2011
by Tom Igoe

This example code is in the public domain.

// http://www.arduino.cc/en/Tutorial/SerialEvent
*/
// MRF 8 30 2013 try adding some motor control
//#include <AFMotor.h>
//AF_DCMotor motor(4);
//AF_DCMotor motor2(2, MOTOR12_64KHZ); // create motor #2, 64KHz pwm

//AF_DCMotor motor4(4, MOTOR12_64KHZ); // create motor #2, 64KHz pwm

// MRF 11 28 2013 add temp control - library, code and hardware from Adafruit industries
#include "Adafruit_MAX31855.h"

int thermoDO = 5;
int thermoCS = 4;
int thermoCLK = 3;
// optional setlimitF for different message or whatever
const int SetlimitF = 180;

Adafruit_MAX31855 thermocouple(thermoCLK, thermoCS, thermoDO);



#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);

// Select which 'port' M1, M2, M3 or M4. In this case, M1
Adafruit_DCMotor *Motor1 = AFMS.getMotor(1);
// You can also make another motor on port M2
Adafruit_DCMotor *Motor2 = AFMS.getMotor(2);
Adafruit_DCMotor *Motor3 = AFMS.getMotor(3);
Adafruit_DCMotor *Motor4 = AFMS.getMotor(4);


int ledPin=13; //LED connected to pin 13 on Arduino UNO.
int ControllerNum;// first character that comes in from pass-thru program
int BtnNum;// next two numbers to come in
int ThrottleSet;// three digit number from 000-255
int LoopCounter;
int array[25];


void setup() {
// initialize serial:
// Serial.begin(9600);/// works well
// Serial.begin(14400);
// Serial.begin(19200);
// Serial.begin(57600);
Serial.begin(115200);/// this one is working fine -9/12/2013
// clear the array, might want to use an array for each gamepad to store
// status of controls, not sure. Right now only using array[1-7] as an inputbuffer
for (int i=1; i < 26 ; i++)
{
array = 0;

}

ControllerNum=0;
BtnNum=0;
ThrottleSet=0;
AFMS.begin(); // create with the default frequency 1.6KHz
// AFMS.begin(1000); // OR with a different frequency, say 1KHz

}
void loop()
{
uint8_t i;
LoopCounter=LoopCounter+1;
if (Serial.available())
{
delay(20);
for (int i=1; i < 7 ; i++)
{

array = Serial.read()-48;

}


}// end of serial loop now whatever came in on the serial port is flushed but the
// info is in the array

// can have up to 4 XBOX type gamepads, this command came from the one indicated
// in the first position of the serial input
ControllerNum = array[1];

// controller can only be 1-4- I'm going to use 9 as a code for 'all clear' for all controllers
// if the controllernum>4 and less than 9, subtract 4 to get the 'all clear' message for 1 controller
// this saves bandwidth by sending just one byte to signify 'reset all'
// so if a '5' code comes in, the system should take that to mean that all of the controlls on gamepad 1 have beon released

BtnNum=(array[2]*10)+array[3];
// bytes 4-6 are the throttle locations (for buttons 1-10)
// they will be 001 for the rest of the buttons
ThrottleSet=(array[4]*100)+(array[5]*10)+array[6];
if (ControllerNum>0)
{
// for debugging- send back what I got
//Serial.println(ControllerNum);
//Serial.println(BtnNum);
//Serial.println(ThrottleSet);
}
// left stick is button 1, 2, 3, and 4
// button 1 is left stick X axis positive numbers-Up (000-255)
// button 2 is left stick X axis negative numbers-Down (000-255)
// button 3 is left stick Y axis positive numbers-Right (000-255)
// button 4 is left stick Y axis negative numbers-Left (000-255)

// Controller 1 will control motor2 with left stick

switch (ControllerNum)
{
case 1:
// controllerNum is the 'player number'
// I'm making controller 1 the pilot, he gets most of the controls
switch (BtnNum)
{ case 1:
Motor1->run(FORWARD);
Motor1->setSpeed(ThrottleSet);
Motor2->run(FORWARD);
Motor2->setSpeed(ThrottleSet);
Motor3->run(FORWARD);
Motor3->setSpeed(ThrottleSet);
Motor4->run(FORWARD);
Motor4->setSpeed(ThrottleSet);

//motor2.run(FORWARD);
//motor2.setSpeed(ThrottleSet);

// want to send some gamepad feedback?
Serial.print("FB");// signal that you're sending a feedback command
Serial.print(ControllerNum);// controller num
Serial.print(9);// first param is left motor (low freq- 0-9)
Serial.println(9);// Second param is right motor (high freq- 0-9)



if (ThrottleSet<20)
{
Motor1->run(RELEASE);
Motor2->run(RELEASE);
Motor3->run(RELEASE);
Motor4->run(RELEASE);
Serial.print("FB");// signal that you're sending a feedback command
Serial.print(ControllerNum);// controller num
Serial.print(0);// first param is left motor (low freq- 0-9)
Serial.println(0);// Second param is right motor (high freq- 0-9)

}

break;
case 2:
Motor1->run(BACKWARD);
Motor1->setSpeed(ThrottleSet);
Motor2->run(BACKWARD);
Motor2->setSpeed(ThrottleSet);
Motor3->run(BACKWARD);
Motor3->setSpeed(ThrottleSet);
Motor4->run(BACKWARD);
Motor4->setSpeed(ThrottleSet);

// motor2.run(BACKWARD);
// motor2.setSpeed(ThrottleSet);
// try some feedback
Serial.print("FB");// signal that you're sending a feedback command
Serial.print(ControllerNum);// controller num
Serial.print(0);// first param is left motor (low freq- 0-9)
Serial.println(3);// Second param is right motor (high freq- 0-9)

if (ThrottleSet<20)
{Motor1->run(RELEASE);
Motor2->run(RELEASE);
Motor3->run(RELEASE);
Motor4->run(RELEASE);
Serial.print("FB");// signal that you're sending a feedback command
Serial.print(ControllerNum);// controller num
Serial.print(0);// first param is left motor (low freq- 0-9)
Serial.println(0);// Second param is right motor (high freq- 0-9)

}
break;}
// add all 24 cases here for controller 1

break;
//********************Anything scoped to the first controller should be above here
case 2:// controllerNum=2
{ // controllerNum =2 can only turn on and off the LED with his left trigger

}

break;



// ControllerNum=2*********************************END*************
case 5://
// controllerNum is the 'player number'
// I'm making controller 1 the pilot, he gets most of the controls
// code '5' is the 'all clear' code for controller 1- implement whatever changes that means (retain cruise or trim for some types of controllers,
// reset all motors for others- whatever you decide should happen when the controller is released.
// this uses less bandwidth than sending a reset for any button, let alone all of them.
//motor2.run(RELEASE);



break;

case 9:
// set all to default settings, turn off all motors (unless something should retain state at this point.
// 9 means all controllers have been released completely


break;
}
// end of switch for controllerNum



delay (10);


for (int i=1; i < 7 ; i++)
{
array = 0;
}

// print the temp coming in from thermocouple
if (LoopCounter>100)// seems to be about once every second or so at 100
{

Serial.print("Temp=");
Serial.print(thermocouple.readFarenheit());
Serial.println(" deg. F");
// reset it, only print ever 100 loops?
LoopCounter=0;
}


}
Tal
Posts: 47
Joined: Feb 7th, 2013, 8:10 pm

Re: New ROV - The Mimee

Post by Tal »

a_shorething wrote://#include <AFMotor.h>#include <Adafruit_MotorShield.h>#include "utility/Adafruit_PWMServoDriver.h"
Hi a_shorething,

Thanks heaps for posting your code! With the AFMotor and Adafruit libraries, it all looks a little foreign to me so I'll have to look over it a couple of times when I've got a few quiet minutes up my sleeve. It's been really exciting looking at how you've approached the challenge and I look forward to getting my head around it.
a_shorething
Posts: 289
Joined: Sep 10th, 2013, 5:26 pm
Location: New Jersey Shore

Re: New ROV - The Mimee

Post by a_shorething »

Tal wrote:
a_shorething wrote://#include <AFMotor.h>#include <Adafruit_MotorShield.h>#include "utility/Adafruit_PWMServoDriver.h"
Hi a_shorething,

Thanks heaps for posting your code! With the AFMotor and Adafruit libraries, it all looks a little foreign to me so I'll have to look over it a couple of times when I've got a few quiet minutes up my sleeve. It's been really exciting looking at how you've approached the challenge and I look forward to getting my head around it.
Yeah, The AFMotor thing is probably not the way I'm going to be doing it in my final version because although they are on version 2.0 of their motor shield, it still can only handle 2 amps and it's even a little iffy at that draw. I tried it and it's just not going to work.

That is basically taking the place of a procedure that will accept parameters and pass them through to the motor driver using I2C addresses and converting the works 'FORWARD' and 'REVERSE' from English into code like 1 and 0 or high and low or whatever and also converting the PWM signal from a single byte (0-255) into whatever their native PWM frequency needs (which may or may not be 0-255, I'm not sure). YMMV :)


Once I get my new motor drivers I'll update the code and try to get a working version in serial mode before switching to Ethernet so I'll post again when I get that done.
Post Reply