Proyecto I&P2024-1: Robot bailarín / Grupo 2
Título | Proyecto I&P2024-1: Robot bailarín / Grupo 2 |
---|---|
Tipo de Proyecto | Proyecto de Taller |
Palabras Clave | proyectoarduino |
Período | 2024-2024 |
Asignatura | Interacción y Performatividad |
Del Curso | Interacción y Performatividad 2024-1 |
Carreras | Diseño |
Alumno(s) | Catalina España Veas, Constanza Cortes Madrid, Carla Bejares |
Profesor | Franco Gnecco |
PROYECTO ROBOT BAILARÍN
Proyecto base MiniZowi Bluetooth Dancing Controled Robot
El proyecto consiste en un robot cúbico bípedo, el cual mediante el movimiento de sus piernas asemeje un baile.
Se plantea la posibilidad de reemplazar los sensores que asemejan los ojos, por una matriz LED la cual permita mostrar diferentes expresiones en los ojos.
ESTUDIO PREVIO
Se realiza un estudio inicial del funcionamiento de los elementos que componen el proyecto, probando de esta manera de forma individual cada parte que dará vida al robot.
Servomotor
Componentes
- Arduino UNO R3
- Servomotor x4
- Protoboard
Diagrama de conexión
Código en arduino
//---------------------------------------------------------------- //-- Otto All moves test //-- Otto DIY invests time and resources providing open source code and hardware, //-- please support by purchasing kits from https://www.ottodiy.com/ //-- Make sure to have installed all libraries: https://github.com/OttoDIY/OttoDIYLib //----------------------------------------------------------------- #include <Otto.h> Otto Otto; //This is Otto! #define LeftLeg 2 #define RightLeg 3 #define LeftFoot 4 #define RightFoot 5 #define Buzzer 13 #define DIN A3 // Data In pin #define CS A2 // Chip Select pin #define CLK A1 // Clock pin #define Orientation 1 // 8x8 LED Matrix orientation Top = 1, Bottom = 2, Left = 3, Right = 4 /////////////////////////////////////////////////////////////////// //-- Setup ------------------------------------------------------// /////////////////////////////////////////////////////////////////// void setup(){ Otto.init(LeftLeg, RightLeg, LeftFoot, RightFoot, true, Buzzer); //Set the servo pins and Buzzer pin Otto.initMATRIX( DIN, CS, CLK, Orientation); Otto.sing(S_connection); //Otto wake up! Otto.home(); delay(50); Otto.playGesture(OttoHappy); } /////////////////////////////////////////////////////////////////// //-- Principal Loop ---------------------------------------------// /////////////////////////////////////////////////////////////////// void loop() { Otto.walk(2,1000,1); //2 steps, "TIME". IF HIGHER THE VALUE THEN SLOWER (from 600 to 1400), 1 FORWARD Otto.walk(2,1000,-1); //2 steps, T, -1 BACKWARD Otto.turn(2,1000,1);//3 steps turning LEFT Otto._tone(10, 3, 1); Otto.bendTones (100, 200, 1.04, 10, 10); Otto.home(); delay(100); Otto.turn(2,1000,-1);//3 steps turning RIGHT Otto.bend (1,500,1); //usually steps =1, T=2000 Otto.bend (1,2000,-1); Otto.shakeLeg (1,1500, 1); Otto.home(); delay(100); Otto.shakeLeg (1,2000,-1); Otto.moonwalker(3, 1000, 25,1); //LEFT Otto.moonwalker(3, 1000, 25,-1); //RIGHT Otto.crusaito(2, 1000, 20,1); Otto.crusaito(2, 1000, 20,-1); delay(100); Otto.flapping(2, 1000, 20,1); Otto.flapping(2, 1000, 20,-1); delay(100); Otto.swing(2, 1000, 20); Otto.tiptoeSwing(2, 1000, 20); Otto.jitter(2, 1000, 20); //(small T) Otto.updown(2, 1500, 20); // 20 = H "HEIGHT of movement"T Otto.ascendingTurn(2, 1000, 50); Otto.jump(1,500); // It doesn't really jumpl ;P Otto.home(); delay(100); Otto.sing(S_cuddly); Otto.sing(S_OhOoh); Otto.sing(S_OhOoh2); Otto.sing(S_surprise); Otto.sing(S_buttonPushed); Otto.sing(S_mode1); Otto.sing(S_mode2); Otto.sing(S_mode3); Otto.sing(S_sleeping); Otto.sing(S_fart1); Otto.sing(S_fart2); Otto.sing(S_fart3); Otto.sing(S_happy); Otto.sing(S_happy_short); Otto.sing(S_superHappy); Otto.sing(S_sad); Otto.sing(S_confused); Otto.sing(S_disconnection); delay(100); Otto.playGesture(OttoHappy); Otto.playGesture(OttoSuperHappy); Otto.playGesture(OttoSad); Otto.playGesture(OttoVictory); Otto.playGesture(OttoAngry); Otto.playGesture(OttoSleeping); Otto.playGesture(OttoFretful); Otto.playGesture(OttoLove); Otto.playGesture(OttoConfused); Otto.playGesture(OttoFart); Otto.playGesture(OttoWave); Otto.playGesture(OttoMagic); Otto.playGesture(OttoFail); Otto.home(); delay(100); Otto.putMouth(zero); delay(100); Otto.putMouth(one); delay(100); Otto.putMouth(two); delay(100); Otto.putMouth(three); delay(100); Otto.putMouth(four); delay(100); Otto.putMouth(five); delay(100); Otto.putMouth(6); delay(100); Otto.putMouth(7); delay(100); Otto.putMouth(8); delay(100); Otto.putMouth(9); delay(100); Otto.putMouth(smile); delay(100); Otto.putMouth(happyOpen); delay(100); Otto.putMouth(happyClosed); delay(100); Otto.putMouth(heart); delay(100); Otto.putMouth(angry); delay(100); Otto.putMouth(smallSurprise); delay(100); Otto.putMouth(bigSurprise); delay(100); Otto.putMouth(tongueOut); delay(100); Otto.putMouth(confused); delay(100); Otto.putMouth(21); //diagonal delay(100); Otto.putMouth(27); //interrogation delay(100); Otto.putMouth(23); //sad open delay(100); Otto.putMouth(24); //sad closed delay(100); Otto.putMouth(vamp1); delay(100); Otto.putMouth(vamp2); delay(100); Otto.putMouth(xMouth); delay(100); Otto.putMouth(okMouth); delay(100); Otto.putMouth(thunder); delay(100); Otto.putMouth(lineMouth); delay(100); Otto.putMouth(culito); delay(100); Otto.putAnimationMouth(littleUuh,0); delay(1000); Otto.putAnimationMouth(dreamMouth, 0); delay(1000); Otto.putAnimationMouth(dreamMouth, 1); delay(1000); Otto.putAnimationMouth(dreamMouth, 2); delay(1000); }
Prueba de movimiento previa
Componentes
- Arduino UNO R3
- Servomotor x4
- Protoboard
Diagrama de conexión
Código en arduino
// C++ code // #include <Servo.h> Servo myservo1; Servo myservo2; Servo myservo3; Servo myservo4; void setup() { myservo1.attach(8); myservo2.attach(9); myservo3.attach(10); myservo4.attach(11); myservo1.write(45); myservo2.write(45); myservo3.write(45); myservo4.write(45); } void loop() { myservo1.write(180); myservo2.write(0); myservo3.write(180); myservo4.write(0); delay(1500); myservo1.write(0); myservo2.write(180); myservo3.write(0); myservo4.write(180); delay(3500); }
Explicación
- #include <Servo.h> : Define la librería Servo en la cual se trabajará, bajo esta fila se deben declarar cada uno de los servomotores, en este caso enumerados del 1 al 4.
- myservo1.attach(8); : Corresponde al servomotor 1 asociado al pin 8.
- myservo1.write(45); : Posicionamiento del eje a 45°.
- delay(1500); : Tiempo en que se efectuara el movimiento de los servo, en este caso 1,5s .
Enlace proyecto Tinkercad
Matriz LED
Componentes
- Arduino UNO R3
- Módulo MAX7219 Matriz LED 8x8 Rojo
- Protoboard
Diagrama de conexión
Código en arduino
Mediante este código se trabaja la visualización de un ojo en movimiento en la matriz LED.
/*Conecciones Pines: 11 = DIN 12 =CLK 10 = CS 5V - GND LED Matrix Sprite Generator:https://embed.plnkr.co/3VUsekP3jC5xwSIQDVHx/preview */ #include "LedControl.h" // Libreria LedControl lc=LedControl(11, 12, 10, 1); //Pines + 2 Matriz "max 8" #define demora 1000 //1Sg byte Ojo_centro[8] = { B00000000, B01111110, B11111111, B11100111, B11100111, B11111111, B01111110, B00000000 }; byte Inferior_derecho[8] = { B00000000, B01111110, B11111001, B11111001, B11111111, B11111111, B01111110, B00000000 }; byte Inferior_izquierdo[8] = { B00000000, B01111110, B11111111, B11111111, B11110011, B11110011, B01111110, B00000000 }; byte Cento_derecho[8] = { B00000000, B01111110, B11100111, B11100111, B11111111, B11111111, B01111110, B00000000 }; byte Cento_izquierdo[8] = { B00000000, B01111110, B11111111, B11111111, B11100111, B11100111, B01111110, B00000000 }; byte Inferior_centro[8] = { B00000000, B01111110, B11111111, B11111001, B11111001, B11111111, B01111110, B00000000 }; byte superior_derecho[8] = { B00000000, B01111110, B11001111, B11001111, B11111111, B11111111, B01111110, B00000000 }; byte superior_izquierdo[8] = { B00000000, B01111110, B11111111, B11111111, B11001111, B11001111, B01111110, B00000000 }; byte superior_centro[8] = { B00000000, B01111110, B11111111, B10011111, B10011111, B11111111, B01111110, B00000000 }; void setup() { //Matriz 1 lc.shutdown(0,false); // enciende la matriz lc.setIntensity(0,4); // establece brillo lc.clearDisplay(0); // Se limpia la matriz } void loop() { mostrar_ojo_centro (); //Movimiento 1 delay(demora); //Tiempo 1000 Milisendos mostrar_Inferior_derecho(); //Movimiento 2 delay(demora); //Tiempo 1000 Milisendos mostrar_Inferior_izquierdo(); //Movimiento 3 delay(demora); //Tiempo 1000 Milisendos mostrar_Inferior_centro(); //Movimiento 4 delay(demora); //Tiempo 1000 Milisendos mostrar_superior_derecho(); //Movimiento 5 delay(demora); //Tiempo 1000 Milisendos mostrar_superior_izquierdo(); //Movimiento 6 delay(demora); //Tiempo 1000 Milisendos mostrar_superior_centro(); //Movimiento 7 delay(demora); //Tiempo 1000 Milisendos mostrar_Cento_izquierdo(); //Movimiento 8 delay(demora); //Tiempo 1000 Milisendos mostrar_Cento_derecho(); //Movimiento 9 delay(demora); //Tiempo 1000 Milisendos } //////////////////////////////////////////////////////////////// //Orden de mostrar en matriz 8x8 void mostrar_ojo_centro() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,Ojo_centro[i]);//Matriz 1 } } void mostrar_Inferior_derecho() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,Inferior_derecho[i]);//Matriz 1 } } void mostrar_Inferior_izquierdo() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,Inferior_izquierdo[i]);//Matriz 1 } } void mostrar_Inferior_centro() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,Inferior_centro[i]);//Matriz 1 } } void mostrar_superior_derecho() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,superior_derecho[i]);//Matriz 1 } } void mostrar_superior_izquierdo() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,superior_izquierdo[i]);//Matriz 1 } } void mostrar_superior_centro() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,superior_centro[i]);//Matriz 1 } } void mostrar_Cento_izquierdo() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,Cento_izquierdo[i]);//Matriz 1 } } void mostrar_Cento_derecho() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,Cento_derecho[i]);//Matriz 1 } }
PROYECTO FINAL
Componentes
- Arduino UNO R3
- Servomotor x4
- Protoboard
- Módulo MAX7219 Matriz LED 8x8 Rojo
- Módulo Bluetooth HC-06
Diagrama de conexión
Código en arduino
El siguiente código permite al robot realizar los movimientos de "baile" asociados a los servomotores, asimismo se permite la visualización del ojo mediante la matriz LED.
Para poder indicar los movimientos a realizar se utiliza un modulo bluetooth el cual se asocia a la aplicación para celular de zowi
//---------------------------------------------------------------- //-- Zowi basic firmware v2 //-- (c) BQ. Released under a GPL licencse //-- 04 December 2015 //-- Authors: Anita de Prado: ana.deprado@bq.com //-- Jose Alberca: jose.alberca@bq.com //-- Javier Isabel: javier.isabel@bq.com //-- Juan Gonzalez (obijuan): juan.gonzalez@bq.com //-- Irene Sanz : irene.sanz@bq.com //----------------------------------------------------------------- //-- Experiment with all the features that Zowi have! //----------------------------------------------------------------- #include <Servo.h> #include <Oscillator.h> #include <EEPROM.h> #include <BatReader.h> #include <US.h> #include <LedMatrix.h> #include "LedControl.h" // Libreria //-- Library to manage external interruptions #include <EnableInterrupt.h> //-- Library to manage serial commands #include <ZowiSerialCommand.h> ZowiSerialCommand SCmd; //The SerialCommand object //-- Zowi Library #include <Zowi.h> Zowi zowi; //This is Zowi!! //--------------------------------------------------------- //-- Configuration of pins where the servos are attached /* --------------- | | | O O | | | YR ==> | | <== YL --------------- || || || || || || RR ==> ----- ------ <== RL ----- ------ */ #define PIN_YL 2 //servo[0] #define PIN_YR 3 //servo[1] #define PIN_RL 4 //servo[2] #define PIN_RR 5 //servo[3] //--------------------------------------------------------- //---Zowi Buttons original dos 6 tres 7 #define PIN_SecondButton 14 #define PIN_ThirdButton 7 /////////////////////////////////////////////////////////////////// //-- Global Variables -------------------------------------------// /////////////////////////////////////////////////////////////////// const char programID[]="ZOWI_BASE_v2"; //Each program will have a ID const char name_fac='$'; //Factory name const char name_fir='#'; //First name //-- Movement parameters int T=1000; //Initial duration of movement int moveId=0; //Number of movement int moveSize=15; //Asociated with the height of some movements //--------------------------------------------------------- //-- Zowi has 5 modes: //-- * MODE = 0: Zowi is awaiting //-- * MODE = 1: Dancing mode! //-- * MODE = 2: Obstacle detector mode //-- * MODE = 3: Noise detector mode //-- * MODE = 4: ZowiPAD or any Teleoperation mode (listening SerialPort). //-- volatile int MODE=0; //State of zowi in the principal state machine. //--------------------------------------------------------- volatile bool buttonPushed=false; //Variable to remember when a button has been pushed volatile bool buttonAPushed=false; //Variable to remember when A button has been pushed volatile bool buttonBPushed=false; //Variable to remember when B button has been pushed unsigned long previousMillis=0; int randomDance=0; int randomSteps=0; bool obstacleDetected = false; /////////////////////////////////////////////////////////////////// //-- Setup ------------------------------------------------------// /////////////////////////////////////////////////////////////////// LedControl lc=LedControl(11, 12, 10, 1); //Pines + 2 Matriz "max 8" byte Ojo_centro[8] = { B00000000, B01111110, B11111111, B11100111, B11100111, B11111111, B01111110, B00000000 }; void setup(){ //Serial communication initialization Serial.begin(115200); //Matriz 1 lc.shutdown(0,false); // enciende la matriz lc.setIntensity(0,4); // establece brillo lc.clearDisplay(0); // Se limpia la matriz pinMode(PIN_SecondButton,INPUT); pinMode(PIN_ThirdButton,INPUT); //Set the servo pins zowi.init(PIN_YL,PIN_YR,PIN_RL,PIN_RR,true); //Uncomment this to set the servo trims manually and save on EEPROM //zowi.setTrims(TRIM_YL, TRIM_YR, TRIM_RL, TRIM_RR); //zowi.saveTrimsOnEEPROM(); //Uncomment this only for one upload when you finaly set the trims. //Set a random seed randomSeed(analogRead(A6)); //Interrumptions enableInterrupt(PIN_SecondButton, secondButtonPushed, RISING); enableInterrupt(PIN_ThirdButton, thirdButtonPushed, RISING); //Setup callbacks for SerialCommand commands SCmd.addCommand("S", receiveStop); // sendAck & sendFinalAck SCmd.addCommand("L", receiveLED); // sendAck & sendFinalAck SCmd.addCommand("T", recieveBuzzer); // sendAck & sendFinalAck SCmd.addCommand("M", receiveMovement); // sendAck & sendFinalAck SCmd.addCommand("H", receiveGesture); // sendAck & sendFinalAck SCmd.addCommand("K", receiveSing); // sendAck & sendFinalAck SCmd.addCommand("C", receiveTrims); // sendAck & sendFinalAck SCmd.addCommand("G", receiveServo); // sendAck & sendFinalAck SCmd.addCommand("R", receiveName); // sendAck & sendFinalAck SCmd.addCommand("E", requestName); SCmd.addCommand("D", requestDistance); SCmd.addCommand("N", requestNoise); SCmd.addCommand("B", requestBattery); SCmd.addCommand("I", requestProgramId); SCmd.addDefaultHandler(receiveStop); for (int k = 0; k < 8; k++) { lc.setRow(0,k,Ojo_centro[k]);//Matriz 1 } //Zowi wake up! zowi.sing(S_connection); zowi.home(); //If Zowi's name is '&' (factory name) means that is the first time this program is executed. //This first time, Zowi mustn't do anything. Just born at the factory! //5 = EEPROM address that contains first name character if (EEPROM.read(5)==name_fac){ EEPROM.put(5, name_fir); //From now, the name is '#' EEPROM.put(6, '\0'); zowi.putMouth(culito); while(true){ delay(1000); } } //Send Zowi name, programID & battery level. requestName(); delay(50); requestProgramId(); delay(50); requestBattery(); //Checking battery ZowiLowBatteryAlarm(); // Animation Uuuuuh - A little moment of initial surprise //----- for(int i=0; i<2; i++){ for (int i=0;i<8;i++){ if(buttonPushed){break;} zowi.putAnimationMouth(littleUuh,i); delay(150); } } //----- //Smile for a happy Zowi :) if(!buttonPushed){ zowi.putMouth(smile); zowi.sing(S_happy); delay(200); } //If Zowi's name is '#' means that Zowi hasn't been baptized //In this case, Zowi does a longer greeting //5 = EEPROM address that contains first name character if (EEPROM.read(5)==name_fir){ if(!buttonPushed){ zowi.jump(1,700); delay(200); } if(!buttonPushed){ zowi.shakeLeg(1,T,1); } if(!buttonPushed){ zowi.putMouth(smallSurprise); zowi.swing(2,800,20); zowi.home(); } } if(!buttonPushed){ zowi.putMouth(happyOpen); } previousMillis = millis(); } /////////////////////////////////////////////////////////////////// //-- Principal Loop ---------------------------------------------// /////////////////////////////////////////////////////////////////// void loop() { if (Serial.available()>0 && MODE!=4){ MODE=4; zowi.putMouth(happyOpen); //Disable Pin Interruptions disableInterrupt(PIN_SecondButton); disableInterrupt(PIN_ThirdButton); buttonPushed=false; } //First attemp to initial software if (buttonPushed){ zowi.home(); delay(100); //Wait for all buttons zowi.sing(S_buttonPushed); delay(200); //Wait for all buttons if ( buttonAPushed && !buttonBPushed){ MODE=1; zowi.sing(S_mode1);} else if (!buttonAPushed && buttonBPushed) { MODE=2; zowi.sing(S_mode2);} else if ( buttonAPushed && buttonBPushed) { MODE=3; zowi.sing(S_mode3);} //else zowi.putMouth(MODE); int showTime = 2000; while((showTime>0)){ //Wait to show the MODE number showTime-=10; delay(10); } zowi.putMouth(happyOpen); buttonPushed=false; buttonAPushed=false; buttonBPushed=false; }else{ switch (MODE) { //-- MODE 0 - Zowi is awaiting //--------------------------------------------------------- case 0: //Every 80 seconds in this mode, Zowi falls asleep if (millis()-previousMillis>=80000){ ZowiSleeping_withInterrupts(); //ZZzzzzz... previousMillis=millis(); } break; //-- MODE 1 - Dance Mode! //--------------------------------------------------------- case 1: randomDance=random(5,21); //5,20 if((randomDance>14)&&(randomDance<19)){ randomSteps=1; T=1600; } else{ randomSteps=random(3,6); //3,5 T=1000; } zowi.putMouth(random(10,21)); for (int i=0;i<randomSteps;i++){ move(randomDance); if(buttonPushed){break;} } break; //-- MODE 2 - Obstacle detector mode //--------------------------------------------------------- case 2: if(obstacleDetected){ if(!buttonPushed){ zowi.putMouth(bigSurprise); zowi.sing(S_surprise); zowi.jump(5, 500); } if(!buttonPushed){ zowi.putMouth(confused); zowi.sing(S_cuddly); } //Zowi takes two steps back for(int i=0;i<3;i++){ if(buttonPushed){break;} zowi.walk(1,1300,-1); } delay(100); obstacleDetector(); delay(100); //If there are no obstacles and no button is pressed, Zowi shows a smile if((obstacleDetected==true)||(buttonPushed==true)){break;} else{ zowi.putMouth(smile); delay(50); obstacleDetector(); } //If there are no obstacles and no button is pressed, Zowi shows turns left for(int i=0; i<3; i++){ if((obstacleDetected==true)||(buttonPushed==true)){break;} else{ zowi.turn(1,1000,1); obstacleDetector(); } } //If there are no obstacles and no button is pressed, Zowi is happy if((obstacleDetected==true)||(buttonPushed==true)){break;} else{ zowi.home(); zowi.putMouth(happyOpen); zowi.sing(S_happy_short); delay(200); } }else{ zowi.walk(1,1000,1); //Zowi walk straight obstacleDetector(); } break; //-- MODE 3 - Noise detector mode //--------------------------------------------------------- case 3: if (zowi.getNoise()>=650){ //740 delay(50); //Wait for the possible 'lag' of the button interruptions. //Sometimes, the noise sensor detect the button before the interruption takes efect if(!buttonPushed){ zowi.putMouth(bigSurprise); zowi.sing(S_OhOoh); if(buttonPushed){break;} zowi.putMouth(random(10,21)); randomDance=random(5,21); move(randomDance); zowi.home(); delay(500); //Wait for possible noise of the servos while get home } if(!buttonPushed){zowi.putMouth(happyOpen);} } break; //-- MODE 4 - ZowiPAD or any Teleoperation mode (listening SerialPort) //--------------------------------------------------------- case 4: SCmd.readSerial(); //If Zowi is moving yet if (zowi.getRestState()==false){ move(moveId); } break; default: MODE=4; break; } } } /////////////////////////////////////////////////////////////////// //-- Functions --------------------------------------------------// /////////////////////////////////////////////////////////////////// //-- Function executed when second button is pushed void secondButtonPushed(){ buttonAPushed=true; if(!buttonPushed){ buttonPushed=true; zowi.putMouth(smallSurprise); } } //-- Function executed when third button is pushed void thirdButtonPushed(){ buttonBPushed=true; if(!buttonPushed){ buttonPushed=true; zowi.putMouth(smallSurprise); } } //-- Function to read distance sensor & to actualize obstacleDetected variable void obstacleDetector(){ int distance = zowi.getDistance(); if(distance<15){ obstacleDetected = true; }else{ obstacleDetected = false; } } //-- Function to receive Stop command. void receiveStop(){ sendAck(); zowi.home(); sendFinalAck(); } //-- Function to receive LED commands void receiveLED(){ //sendAck & stop if necessary sendAck(); zowi.home(); //Examples of receiveLED Bluetooth commands //L 000000001000010100100011000000000 //L 001111111111111111111111111111111 (todos los LED encendidos) unsigned long int matrix; char *arg; char *endstr; arg=SCmd.next(); //Serial.println (arg); if (arg != NULL) { matrix=strtoul(arg,&endstr,2); // Converts a char string to unsigned long integer zowi.putMouth(matrix,false); }else{ zowi.putMouth(xMouth); delay(2000); zowi.clearMouth(); } sendFinalAck(); } //-- Function to receive buzzer commands void recieveBuzzer(){ //sendAck & stop if necessary sendAck(); zowi.home(); bool error = false; int frec; int duration; char *arg; arg = SCmd.next(); if (arg != NULL) { frec=atoi(arg); } // Converts a char string to an integer else {error=true;} arg = SCmd.next(); if (arg != NULL) { duration=atoi(arg); } // Converts a char string to an integer else {error=true;} if(error==true){ zowi.putMouth(xMouth); delay(2000); zowi.clearMouth(); }else{ zowi._tone(frec, duration, 1); } sendFinalAck(); } //-- Function to receive TRims commands void receiveTrims(){ //sendAck & stop if necessary sendAck(); zowi.home(); int trim_YL,trim_YR,trim_RL,trim_RR; //Definition of Servo Bluetooth command //C trim_YL trim_YR trim_RL trim_RR //Examples of receiveTrims Bluetooth commands //C 20 0 -8 3 bool error = false; char *arg; arg=SCmd.next(); if (arg != NULL) { trim_YL=atoi(arg); } // Converts a char string to an integer else {error=true;} arg = SCmd.next(); if (arg != NULL) { trim_YR=atoi(arg); } // Converts a char string to an integer else {error=true;} arg = SCmd.next(); if (arg != NULL) { trim_RL=atoi(arg); } // Converts a char string to an integer else {error=true;} arg = SCmd.next(); if (arg != NULL) { trim_RR=atoi(arg); } // Converts a char string to an integer else {error=true;} if(error==true){ zowi.putMouth(xMouth); delay(2000); zowi.clearMouth(); }else{ //Save it on EEPROM zowi.setTrims(trim_YL, trim_YR, trim_RL, trim_RR); zowi.saveTrimsOnEEPROM(); //Uncomment this only for one upload when you finaly set the trims. } sendFinalAck(); } //-- Function to receive Servo commands void receiveServo(){ sendAck(); moveId = 30; //Definition of Servo Bluetooth command //G servo_YL servo_YR servo_RL servo_RR //Example of receiveServo Bluetooth commands //G 90 85 96 78 bool error = false; char *arg; int servo_YL,servo_YR,servo_RL,servo_RR; arg=SCmd.next(); if (arg != NULL) { servo_YL=atoi(arg); } // Converts a char string to an integer else {error=true;} arg = SCmd.next(); if (arg != NULL) { servo_YR=atoi(arg); } // Converts a char string to an integer else {error=true;} arg = SCmd.next(); if (arg != NULL) { servo_RL=atoi(arg); } // Converts a char string to an integer else {error=true;} arg = SCmd.next(); if (arg != NULL) { servo_RR=atoi(arg); } // Converts a char string to an integer else {error=true;} if(error==true){ zowi.putMouth(xMouth); delay(2000); zowi.clearMouth(); }else{ //Update Servo: int servoPos[4]={servo_YL, servo_YR, servo_RL, servo_RR}; zowi._moveServos(200, servoPos); //Move 200ms } sendFinalAck(); } //-- Function to receive movement commands void receiveMovement(){ sendAck(); if (zowi.getRestState()==true){ zowi.setRestState(false); } //Definition of Movement Bluetooth commands //M MoveID T MoveSize char *arg; arg = SCmd.next(); if (arg != NULL) {moveId=atoi(arg);} else{ zowi.putMouth(xMouth); delay(2000); zowi.clearMouth(); moveId=0; //stop } arg = SCmd.next(); if (arg != NULL) {T=atoi(arg);} else{ T=1000; } arg = SCmd.next(); if (arg != NULL) {moveSize=atoi(arg);} else{ moveSize =15; } } //-- Function to execute the right movement according the movement command received. void move(int moveId){ bool manualMode = false; switch (moveId) { case 0: zowi.home(); break; case 1: //M 1 1000 zowi.walk(1,T,1); break; case 2: //M 2 1000 zowi.walk(1,T,-1); break; case 3: //M 3 1000 zowi.turn(1,T,1); break; case 4: //M 4 1000 zowi.turn(1,T,-1); break; case 5: //M 5 1000 30 zowi.updown(1,T,moveSize); break; case 6: //M 6 1000 30 zowi.moonwalker(1,T,moveSize,1); break; case 7: //M 7 1000 30 zowi.moonwalker(1,T,moveSize,-1); break; case 8: //M 8 1000 30 zowi.swing(1,T,moveSize); break; case 9: //M 9 1000 30 zowi.crusaito(1,T,moveSize,1); break; case 10: //M 10 1000 30 zowi.crusaito(1,T,moveSize,-1); break; case 11: //M 11 1000 zowi.jump(1,T); break; case 12: //M 12 1000 30 zowi.flapping(1,T,moveSize,1); break; case 13: //M 13 1000 30 zowi.flapping(1,T,moveSize,-1); break; case 14: //M 14 1000 20 zowi.tiptoeSwing(1,T,moveSize); break; case 15: //M 15 500 zowi.bend(1,T,1); break; case 16: //M 16 500 zowi.bend(1,T,-1); break; case 17: //M 17 500 zowi.shakeLeg(1,T,1); break; case 18: //M 18 500 zowi.shakeLeg(1,T,-1); break; case 19: //M 19 500 20 zowi.jitter(1,T,moveSize); break; case 20: //M 20 500 15 zowi.ascendingTurn(1,T,moveSize); break; default: manualMode = true; break; } if(!manualMode){ sendFinalAck(); } } //-- Function to receive gesture commands void receiveGesture(){ //sendAck & stop if necessary sendAck(); zowi.home(); //Definition of Gesture Bluetooth commands //H GestureID int gesture = 0; char *arg; arg = SCmd.next(); if (arg != NULL) {gesture=atoi(arg);} else { zowi.putMouth(xMouth); delay(2000); zowi.clearMouth(); } switch (gesture) { case 1: //H 1 zowi.playGesture(ZowiHappy); break; case 2: //H 2 zowi.playGesture(ZowiSuperHappy); break; case 3: //H 3 zowi.playGesture(ZowiSad); break; case 4: //H 4 zowi.playGesture(ZowiSleeping); break; case 5: //H 5 zowi.playGesture(ZowiFart); break; case 6: //H 6 zowi.playGesture(ZowiConfused); break; case 7: //H 7 zowi.playGesture(ZowiLove); break; case 8: //H 8 zowi.playGesture(ZowiAngry); break; case 9: //H 9 zowi.playGesture(ZowiFretful); break; case 10: //H 10 zowi.playGesture(ZowiMagic); break; case 11: //H 11 zowi.playGesture(ZowiWave); break; case 12: //H 12 zowi.playGesture(ZowiVictory); break; case 13: //H 13 zowi.playGesture(ZowiFail); break; default: break; } sendFinalAck(); } //-- Function to receive sing commands void receiveSing(){ //sendAck & stop if necessary sendAck(); zowi.home(); //Definition of Sing Bluetooth commands //K SingID int sing = 0; char *arg; arg = SCmd.next(); if (arg != NULL) {sing=atoi(arg);} else { zowi.putMouth(xMouth); delay(2000); zowi.clearMouth(); } switch (sing) { case 1: //K 1 zowi.sing(S_connection); break; case 2: //K 2 zowi.sing(S_disconnection); break; case 3: //K 3 zowi.sing(S_surprise); break; case 4: //K 4 zowi.sing(S_OhOoh); break; case 5: //K 5 zowi.sing(S_OhOoh2); break; case 6: //K 6 zowi.sing(S_cuddly); break; case 7: //K 7 zowi.sing(S_sleeping); break; case 8: //K 8 zowi.sing(S_happy); break; case 9: //K 9 zowi.sing(S_superHappy); break; case 10: //K 10 zowi.sing(S_happy_short); break; case 11: //K 11 zowi.sing(S_sad); break; case 12: //K 12 zowi.sing(S_confused); break; case 13: //K 13 zowi.sing(S_fart1); break; case 14: //K 14 zowi.sing(S_fart2); break; case 15: //K 15 zowi.sing(S_fart3); break; case 16: //K 16 zowi.sing(S_mode1); break; case 17: //K 17 zowi.sing(S_mode2); break; case 18: //K 18 zowi.sing(S_mode3); break; case 19: //K 19 zowi.sing(S_buttonPushed); break; default: break; } sendFinalAck(); } //-- Function to receive Name command void receiveName(){ //sendAck & stop if necessary sendAck(); zowi.home(); char newZowiName[11] = ""; //Variable to store data read from Serial. int eeAddress = 5; //Location we want the data to be in EEPROM. char *arg; arg = SCmd.next(); if (arg != NULL) { //Complete newZowiName char string int k = 0; while((*arg) && (k<11)){ newZowiName[k]=*arg++; k++; } EEPROM.put(eeAddress, newZowiName); } else { zowi.putMouth(xMouth); delay(2000); zowi.clearMouth(); } sendFinalAck(); } //-- Function to send Zowi's name void requestName(){ zowi.home(); //stop if necessary char actualZowiName[11]= ""; //Variable to store data read from EEPROM. int eeAddress = 5; //EEPROM address to start reading from //Get the float data from the EEPROM at position 'eeAddress' EEPROM.get(eeAddress, actualZowiName); Serial.print(F("&&")); Serial.print(F("E ")); Serial.print(actualZowiName); Serial.println(F("%%")); Serial.flush(); } //-- Function to send ultrasonic sensor measure (distance) void requestDistance(){ zowi.home(); //stop if necessary int distance = zowi.getDistance(); Serial.print(F("&&")); Serial.print(F("D ")); Serial.print(distance); Serial.println(F("%%")); Serial.flush(); } //-- Function to send noise sensor measure void requestNoise(){ zowi.home(); //stop if necessary int microphone= zowi.getNoise(); //analogRead(PIN_NoiseSensor); Serial.print(F("&&")); Serial.print(F("N ")); Serial.print(microphone); Serial.println(F("%%")); Serial.flush(); } //-- Function to send battery voltage percent void requestBattery(){ zowi.home(); //stop if necessary //The first read of the batery is often a wrong reading, so we will discard this value. double batteryLevel = zowi.getBatteryLevel(); Serial.print(F("&&")); Serial.print(F("B ")); Serial.print(batteryLevel); Serial.println(F("%%")); Serial.flush(); } //-- Function to send program ID void requestProgramId(){ zowi.home(); //stop if necessary Serial.print(F("&&")); Serial.print(F("I ")); Serial.print(programID); Serial.println(F("%%")); Serial.flush(); } //-- Function to send Ack comand (A) void sendAck(){ delay(30); Serial.print(F("&&")); Serial.print(F("A")); Serial.println(F("%%")); Serial.flush(); } //-- Function to send final Ack comand (F) void sendFinalAck(){ delay(30); Serial.print(F("&&")); Serial.print(F("F")); Serial.println(F("%%")); Serial.flush(); } //-- Functions with animatics //-------------------------------------------------------- void ZowiLowBatteryAlarm(){ double batteryLevel = zowi.getBatteryLevel(); if(batteryLevel<45){ while(!buttonPushed){ zowi.putMouth(thunder); zowi.bendTones (880, 2000, 1.04, 8, 3); //A5 = 880 delay(30); zowi.bendTones (2000, 880, 1.02, 8, 3); //A5 = 880 zowi.clearMouth(); delay(500); } } } void ZowiSleeping_withInterrupts(){ int bedPos_0[4]={100, 80, 60, 120}; //{100, 80, 40, 140} if(!buttonPushed){ zowi._moveServos(700, bedPos_0); //800 } for(int i=0; i<4;i++){ if(buttonPushed){break;} zowi.putAnimationMouth(dreamMouth,0); zowi.bendTones (100, 200, 1.04, 10, 10); if(buttonPushed){break;} zowi.putAnimationMouth(dreamMouth,1); zowi.bendTones (200, 300, 1.04, 10, 10); if(buttonPushed){break;} zowi.putAnimationMouth(dreamMouth,2); zowi.bendTones (300, 500, 1.04, 10, 10); delay(500); if(buttonPushed){break;} zowi.putAnimationMouth(dreamMouth,1); zowi.bendTones (400, 250, 1.04, 10, 1); if(buttonPushed){break;} zowi.putAnimationMouth(dreamMouth,0); zowi.bendTones (250, 100, 1.04, 10, 1); delay(500); } if(!buttonPushed){ zowi.putMouth(lineMouth); zowi.sing(S_cuddly); } zowi.home(); if(!buttonPushed){zowi.putMouth(happyOpen);} }
DESARROLLO PROYECTO
Piezas
El robot se compone de 6 piezas las cuales se encuentran en MiniZowi robot. Para esta propuesta se editó la cabeza de manera que fuese posible colocar una matriz LED.
Impresión piezas
Proceso armado
FUNCIONAMIENTO
Videos
Video
Video 2