Autore archivio: ricecipriani103
Second version of PESCOLINO (code name Green-bottle)
Snapshot
Test Drive
Electric connection
Android code and program
The program for Android was created entirely by me (Rice Cipriani) Based on the libraries “Candroid engine” and “Amarino 2“. The program provides to design a graphical interface through Candroid and to receive and send messages via bluetooth by Amarino.
The GUI commands Pescolino as this:
Download Android Program: Pescolino.apk
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:
First version of PESCOLINO