Ho pensato di utilizzare una scheda I/O e un computer (quelli a cubetto che vanno a 12v) perchè è fondamentale che la mia creazione abbia le capacità di calcolo di un computer.
Il sistema operativo è indifferente ora c'è xp installato ma posso tranquillamente utilizzare una qualsiasi versione di linux come il mio amato ubuntu.
Tutto il codice che ho prodotto è in c. Principalmente le funzionalità del robot dovrebbero essere una grande capacita' di sentire vari input dall'esterno (luce, colore, ultrasonici, piezo input, temp, tilt ecc.) computare e di conseguenza reagire muovendo due servi (muoversi con due ruote + ruotino) ed emettere un output vocale (pensavo con una libreria di c di emulazione vocale). Sto portando avanti il progetto con Francesco Monico presso la NABA, discutero' la mia tesi a Febbraio. Massimo sarei onorato che tu ci sia visto che la tua scheda è stato lo strumento primo di sperimentazione e per me la porta di questo mondo.
Quindi in base a una randomizzazione data da una coltura in vitro di amoebe (o qualsiasi altro organismo, vedi lievito) collegata a psicogalvanoetro + input esterni vengono generate frasi idiomatiche e citazioni di Pessoa e altri scrittori che ragionano su rapporto uomo-macchina. Sarebbe carino anche proiettare uno slideshow oppure un video in un piccolo monitor usb.
Ho pensato anche di utilizzare arduino per tutto il movimento e di input output e utilizzare il computer collegato per la parte di emulazione vocale e produzione di immagini. Solo che non so come farlo. Mi dareste una mano?
Di seguito rilascio tutti i programmi che abbiamo scritto per la parte di movimento e gestione dei sensori:
- Programma che gestisce:
-2 servi
-input sonoro piezo
-output sonoro piezo
-2 winkers
-vari led
Le funzionalita sono:
-iniziare a muoversi solo se c'è tot luce. dopo tot tempo (random) o se riceve input sonori tramite piezo, appena acceso ogni tot curva di un valore random ed evita gli ostacoli sentiti dai winkers (se tocca con i winker accende un led). Dopo tot tocchi smette di muoversi.
#include <Servo.h>
// words for clarity
#define LEFT 1
#define RIGHT 2
#define LEDBICOLOR 0
#define LEDTRICOLOR 1
// parameters
#define BUMPS_TO_STOP 5 // number of obstacles to stop after
#define RANDOM_START_SECONDS 120 // mean time in seconds for random start
#define RANDOM_SOUND_SECONDS 30 // mean time in seconds for random sound
#define RANDOM_STEER_SECONDS 3 // mean time in seconds for random steering
#define BACKWARD_MSECONDS 800 // time to go back after hitting an obstacle in milliseconds
#define ROTATION_MSECONDS 500 // duration of the rotation in milliseconds
#define STEER_MSECONDS 1000 // duration of the random steering
#define SPEED 100 // speed to go
#define STEER_PERCENT 3 // percent of SPEED to set one of the servos to steer
#define SNDMEAN 150 // number of samples to mean
// digital pins
#define ledPin1 2 // LED 0 red
#define ledPin2 3 // LED 0 green
#define ledPin3 4 // LED 1 blue
#define ledPin4 5 // LED 1 green
#define ledPin5 6 // LED sensor
#define winkerPin1 7 // winker LEFT
#define winkerPin2 8 // winker RIGHT
#define servoPin1 9 // servo LEFT
#define servoPin2 10 // servo RIGHT
#define outSndPin 11 // speaker
#define ledPin6 12 // LED sensor
// analog pins
#define inSndPin 5 // sound sensor
// variables
float actualSpeed = 0.0; // percent of actual moving speed we are accelerating to
boolean moving = false; // stopped or moving
int speedLeft = 0; // speed we want on left servo
int speedRight = 0; // speed we want on right servo
Servo left;
Servo right;
int contact = 0; // did we hit? where?
int contactCount = 0; // number of hits since start
int contactStep = 0; // part of the hit manouver we are in
long contactTime = 0; // time of hitting
boolean steering = false; // steering or going straight
boolean lightCheck = true;
long lightTime = 0; // time of last light check
long startTime = 0; // time of last random start
long steerTime = 0; // time of last random steering change
long soundTime = 0; // time of last random sound
int meanSnd[SNDMEAN]; // past values of sound sensor
long meanSndCount = 0; // number of values stored
// setup
void setup() {
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin6, OUTPUT);
pinMode(winkerPin1, INPUT);
pinMode(winkerPin2, INPUT);
left.attach(servoPin1);
right.attach(servoPin2);
pinMode(outSndPin, OUTPUT);
randomSeed(analogRead(0));
digitalWrite(ledPin6, LOW);
Serial.begin(9600);
}
// winkers
int checkContact() {
if(digitalRead(winkerPin1) == LOW)
return LEFT;
if(digitalRead(winkerPin2) == LOW)
return RIGHT;
return 0;
}
// servo
void servoContinue() {
if(moving) {
if((actualSpeed < 1)) {
actualSpeed += 0.009;
}
if(steering && (steerTime < millis() - STEER_MSECONDS)) {
speedLeft = speedRight = max(speedLeft, speedRight);
steering = false;
steerTime = millis();
}
}
servoSpeed(LEFT, round(speedLeft * actualSpeed));
servoSpeed(RIGHT, round(speedRight * actualSpeed));
}
void servoGo(int speed) {
if(speed < 0) {
setLed(LEDBICOLOR, 1);
}
else {
setLed(LEDBICOLOR, 0);
}
speedLeft = speedRight = speed;
servoReset();
}
void servoReset() {
actualSpeed = 0;
servoContinue();
}
void servoRotate(int side) {
setLed(LEDBICOLOR, 2);
switch(side) {
case LEFT:
speedLeft = 40;
speedRight = -40;
break;
case RIGHT:
speedLeft = -40;
speedRight = 40;
break;
}
servoReset();
}
void servoSpeed(int side, int speed) {
speed = speed * 90 / 100;
switch(side) {
case LEFT:
left.write(90 + speed);
break;
case RIGHT:
right.write(90 - speed);
break;
}
}
void servoSteer(int side) {
steering = true;
steerTime = millis();
switch(side) {
case LEFT:
speedLeft = round(speedLeft * STEER_PERCENT / 100.0);
break;
case RIGHT:
speedRight = round(speedRight * STEER_PERCENT / 100.0);
break;
}
}
// LED
void setLed(int led, int state) {
switch(led) {
case LEDBICOLOR:
switch(state) {
case 0:
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
break;
case 1:
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
break;
case 2:
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
break;
}
break;
case LEDTRICOLOR:
switch(state) {
case 0:
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
break;
case 1:
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, HIGH);
break;
case 2:
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, HIGH);
break;
}
}
}
// sound
void sndPlay(int sound) {
switch(sound) {
case 0: // sound when hitting an obstacle
sndTone(1275);
sndTone(1915);
sndTone(2000);
break;
case 1: // sound when starting
sndTone(2100);
sndTone(1500);
sndTone(1200);
break;
case 2: // random sound
for(int i = 0; i < 3; i++)
sndTone(random(1200, 3000));
break;
}
}
void sndTone(int tone) {
for(long i = 0; i < 80000; i += tone * 2) {
digitalWrite(outSndPin, HIGH);
delayMicroseconds(tone);
digitalWrite(outSndPin, LOW);
delayMicroseconds(tone);
}
}
// movement
void start() {
contactCount = 0;
steerTime = soundTime = millis();
moving = true;
servoGo(SPEED);
sndPlay(1);
setLed(LEDTRICOLOR, 2);
}
void stop() {
startTime = millis();
meanSndCount = 0;
moving = false;
servoGo(0);
setLed(LEDTRICOLOR, 0);
}
void hit() {
contactCount++;
servoGo(-SPEED);
sndPlay(0);
}
// time
long randomTime(long since, long about) {
return since - (millis() - round(about * random(5, 15) / 10));
}
// main loop
void loop() {
if(! moving) {
if(lightTime < millis() - 1000) {
lightTime = millis();
long light = 0;
for(int i = 0; i < 3; i++) {
pinMode(ledPin5, OUTPUT);
digitalWrite(ledPin5, HIGH);
pinMode(ledPin5, INPUT);
digitalWrite(ledPin5, LOW);
for(; light < 90000; light++)
if(digitalRead(ledPin5) == 0)
break;
}
lightCheck = light < 10000;
Serial.println(light);
if(lightCheck)
setLed(LEDBICOLOR, 2);
else
setLed(LEDBICOLOR, 1);
}
if(lightCheck && randomTime(startTime, RANDOM_START_SECONDS * 1000L) < 0)
start();
}
else if(contactStep == 0) {
if(randomTime(soundTime, RANDOM_SOUND_SECONDS * 1000L) < 0) {
soundTime = millis();
sndPlay(2);
}
// check number of hits
int remaining = BUMPS_TO_STOP - contactCount;
if(remaining == 0)
stop(); // too many hits, stop ;)
else if(remaining == 1)
setLed(LEDTRICOLOR, 1);
Quello che manca ora è implementare un sensore di temperatura, lo psicogalvanometro nella coltura in vitro e l'emulazione vocale. Ora mi chiedo. E' possibile ottenere un input o piu' input da arduino collegato via usb e generare frasi con libreria di emulazione vocale caricata direttamente nel programma di arduino?
Se questo e' possibile con un arduino MEGA potrei liberarmi del "mostro" sd84 ;D