Autore archivio: ricecipriani103

ArduinoBT code

This code is suitable for ArduinoBT but you can also use a Bluetooth shield for Arduino (though often carefully to 57600 baud).

Requirements:
Library meetandroid.h
Library afmotor.h
Library servo.h (using Arduino 0019 is already included)

       /*
Pescolino.pde - Arduino code for PESCOLINO
Copyright (c) 2010 Rice Cipriani. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
*/
       #include <Servo.h>
#include <MeetAndroid.h> #include <AFMotor.h>
       
MeetAndroid meetAndroid(error);
void error(uint8_t flag, uint8_t values){
Serial.print("ERROR: ");
Serial.print(flag);
Serial.print(";");
}
int batteryPin;
int mode=4;
int state=0;
int verso=1;
int ledBlu = 2;
int ledBianco = 13;
int oldbussola;
int vel;
int rot;
int oldVel;
int inInt[3];
Servo ciottDx; // seconda ciottolina da svuotare
Servo timone; // timone

//Servo timone; // timone
//Servo ciottSx; // ciottolina da svuotare
AF_DCMotor motor(4,MOTOR34_64KHZ);
int bussola; // variable to read the bussolaue from the analog pin
void setup()
{
// use the baud rate your bluetooth module is configured to
// not all baud rates are working well, i.e. ATMEGA168 works best with 57600
Serial.begin(115200);
oldbussola=180;
oldVel=0;
vel=0;
// register callback functions, which will be called when an associated event occurs.
// - the first parameter is the name of your function (see below)
// - match the second parameter ('A', 'B', 'a', etc...) with the flag on your Android application
meetAndroid.registerFunction(orientation, 'A');
meetAndroid.registerFunction(orientationG, 'G');
meetAndroid.registerFunction(cambioStato, 'S');
meetAndroid.registerFunction(cambioModo, 'M');
meetAndroid.registerFunction(dirTimone, 'T');
meetAndroid.registerFunction(velocita, 'V');
meetAndroid.registerFunction(svuotaCiottole, 'C');
meetAndroid.registerFunction(richiestaBatteria, 'R');
pinMode(ledBlu, OUTPUT);
pinMode(ledBianco, OUTPUT);
digitalWrite(ledBlu, HIGH);
digitalWrite(ledBianco, HIGH);

motor.run(FORWARD);

ciottDx.attach(3); // attaches the servo on pin 9 to the servo object
ciottDx.write(0); // sets the servo position according to the scaled bussolaue

timone.attach(4); // attaches the servo on pin 9 to the servo object
timone.write(0); // sets the servo position according to the scaled bussolaue
delay(300);
timone.write(180); // sets the servo position according to the scaled bussolaue
delay(300);
timone.write(0); // sets the servo position according to the scaled bussolaue
delay(300);
timone.write(70); // sets the servo position according to the scaled bussolaue
meetAndroid.send(" ->Sono pronto");
meetAndroid.send(";");
}

void loop()
{
meetAndroid.receive(); // you need to keep this in your loop() to receive events
delay(150); // waits for the servo to get there
//digitalWrite(ledBlu, LOW);
digitalWrite(ledBianco, LOW);
}

void richiestaBatteria(byte flag, byte numOfValues)
{
digitalWrite(ledBianco, HIGH);
batteryPin=meetAndroid.getInt();
meetAndroid.send(" ->Batteria ");
meetAndroid.send(batteryPin+1);
meetAndroid.send(" ->: ");
int liv=analogRead(batteryPin);
if (liv<650)
{
digitalWrite(ledBlu, HIGH);
}
else
{
digitalWrite(ledBlu, LOW);
}
int par=int(float(liv)/100.0);
meetAndroid.send(par);
liv=liv-(par*100);
par=int(float(liv)/10.0);
meetAndroid.send(par);
liv=liv-(par*10);
meetAndroid.send(liv);
meetAndroid.send(" ->‰");
meetAndroid.send("§");
}
void cambioModo(byte flag, byte numOfValues)
{
digitalWrite(ledBianco, HIGH);
mode=meetAndroid.getInt();
//meetAndroid.send("Impostato modo " + mode);
if (mode==1)
{
//meetAndroid.send("1:velocità ridotta e curvature larghe");
meetAndroid.send(" ->Velocità ridotta e curvature larghe");
meetAndroid.send(";");
}
if (mode==2)
{
//meetAndroid.send("2:velocità estesa e curvature ridotte");
meetAndroid.send(" ->Velocità estesa e curvature ridotte");
meetAndroid.send(";");
}
if (mode==3)
{
//meetAndroid.send("3:tutto ridotto");
meetAndroid.send(" ->Velocità e curvature ridotte");
meetAndroid.send(";");
}
if (mode==4)
{
//meetAndroid.send("4:tutto esteso");
meetAndroid.send(" ->Velocità e curvature estese");
meetAndroid.send(";");
}
}

void cambioStato(byte flag, byte numOfValues)
{
digitalWrite(ledBianco, HIGH);
state=meetAndroid.getInt();
if (state==0)
{
//meetAndroid.send("tutti i comandi");
meetAndroid.send(" ->Muovo tutto");
meetAndroid.send(";");
}
if (state==1)
{//funzionamento delle sole ciottole
motor.run(RELEASE);
timone.write(0);
//meetAndroid.send("solo ciottole");
meetAndroid.send(" ->Muovo solo le ciottole");
meetAndroid.send(";");
}
if (state==2)
{//funzionamento del solo movimento dello scafo
ciottDx.write(0); // sets the servo position according to the scaled bussolaue
//meetAndroid.send("pescolino solamente");
meetAndroid.send(" ->Muovo solo lo scafo");
meetAndroid.send(";");
}
}

void dirTimone(byte flag, byte numOfValues){
digitalWrite(ledBianco, HIGH);
bussola=meetAndroid.getInt();
if (state==0 || state==2){
if (bussola<180)
{
if (bussola>89)
{bussola=180;}//360-bussola;}
else
{bussola=0;}
}
else
{bussola=360-bussola;}
if (mode==2 || mode ==3)
{
bussola=map(bussola,0,180,30,110);
}
timone.write(bussola); // sets the servo position according to the scaled bussolaue
//meetAndroid.send("Timone " + bussola);
}
}
void velocita(byte flag, byte numOfValues){
digitalWrite(ledBianco, HIGH);
vel=meetAndroid.getInt();
if ((state==0 || state==2)){

if (vel>-45 && vel<45)
{
if (vel>0)
{vel=0;}
oldVel=map(vel,-45,0,0,255);
motor.run(FORWARD);
verso=1;
}
if (vel>-135 && vel<-45)
{
if (vel<-90)
{vel=-90;}
oldVel=map(vel,-45,-90,0,255);
motor.run(BACKWARD);
verso=0;
}
if (mode==1 || mode == 3)
{
oldVel=oldVel/4;
}
motor.setSpeed(oldVel);
//meetAndroid.send("Velocita " + oldVel);
}
}
void svuotaCiottole(byte flag, byte numOfValues){
digitalWrite(ledBianco, HIGH);
rot=meetAndroid.getInt();
if ((state==0 || state==1))
{
digitalWrite(ledBianco, HIGH);
if (rot<20 && rot>-20)
{
ciottDx.write(0);
meetAndroid.send(" ->Ciottola in posizione originale");
meetAndroid.send(";");
}
if (rot<-19)
{
rot=rot=map(rot,-20,-90,0,180);
ciottDx.write(rot);
//meetAndroid.send("Ciottola ruotata " + rot);
meetAndroid.send(" ->Ciottola ruotata ");
meetAndroid.send(rot);
meetAndroid.send(";");
}
}
}

void orientationG(byte flag, byte numOfValues){
orientation(flag,numOfValues);
}
void orientation(byte flag, byte numOfValues)
{
digitalWrite(ledBianco, HIGH);
meetAndroid.getIntValues(inInt);
if (state!=1){
// we use getInt(), since we know only data between 0 and 360 will be sent
vel=inInt[1];

if (vel>-45 && vel<45)
{
if (vel>0)
{vel=0;}
oldVel=map(vel,-45,0,0,255);
motor.run(FORWARD);
verso=1;
}
if (vel>-135 && vel<-44)
{
if (vel<-90)
{vel=-90;}
oldVel=map(vel,-45,-90,0,255);
motor.run(BACKWARD);
verso=0;
}
if (mode==1 || mode == 3)
{
oldVel=oldVel/4;
}
motor.setSpeed(oldVel);
bussola=inInt[0];

if (bussola<180)
{
if (bussola>89)
{bussola=180;}//360-bussola;}
else
{bussola=0;}
}
else
{bussola=360-bussola;}
if (mode==2 || mode ==3)
{
bussola=map(bussola,0,180,30,110);
}
timone.write(bussola); // sets the servo position according to the scaled bussolaue
//meetAndroid.send("Muovo il timone");
}
if (state!=2)
{
digitalWrite(ledBianco, HIGH);
rot=inInt[2];
if (rot<20 && rot>-20)
{
ciottDx.write(0);
//meetAndroid.send("Ciottola in posizione originale");
}
//if (rot>20)
// {
//rot=map(rot,20,90,0,180);
//ciottSx.write(rot);
//meetAndroid.send("Ciottola sinistra");
//}
if (rot<-20)
{
rot=rot=map(rot,-21,-90,0,180);
ciottDx.write(rot);
//meetAndroid.send("Ciottola ruotata: " + rot);
}
}
}

Download file (link)

 

 

Parts List / Cost

  • 3 water bottle (0€)
  • tape (0,50€)
  • hot glue (5€)
  • pieces of wood (0€)
  • silicon (2,5€)
  • 2 led high brightness (2€)
  • 2 Servo Motors (7€)
  • gear for servo (1€)
  • DC motor + propeller (17€)
  • Plastic bowls (4€)
  • saucer (0€ stolen at morther)
  • nails and other metal parts (2€)
  • arduinoBT (100€)
  • Android phone (anything Android like HTC dream or LG Linkme or HTC Desire that I used)

Globally 141€

Realization of Pescolino

Pescolino is made with recycled materials and has a heart device based on Arduino.
The hull is made of three 1.5-liter bottles and pieces of wood.
All the attaches are in hot glue and tape. The keel was made of silicone.

He uses two servo motors for movement and a DC motor for the fan for propulsion. Two status LED and batteries 12 AA batteries or two batteries rechargeable equivalent of 5 volts and 8 volts.

This is a view from top of Pescolino:

 

pescolino schemes.png

 

First version of PESCOLINO

 

Problems:

  • the boat does not keep the route
  • the boat is too light and therefore less stable
  • the boat becomes unbalanced in the emptying of the bowls

Solution:

  • enlargement of the hull
  • creation of keels with silicon
  • more weight with heavier woody material
  • placement of bowls on the centroid