«SCAN-IT»
Autores:
Erik Fernández Orgaz
Alejandro Herrera González
Adrián Leonis García
Introducción del proyecto
Nuestro proyecto se basa en un escáner 3d con varias funcionalidades las cuales son: escáner, cinemática y control manual.
La implementación se ha llevado acabo con: varias piezas impresas en 3d como estructura del proyecto, una placa Arduino uno R3, regulador de voltaje DC-DC, bluetooth hc-06, motor paso a paso, driver controlador motor paso a paso, lcd 16×2, modulo I2C y módulo joystick.
Implementación
LCD y Joystick
Primero empezamos viendo como presentar la interfaz a través del módulo lcd, una vez que lo tuvimos claro, la implementación se llevó a cabo de la siguiente manera: Al tener el modulo I2C se utilizaron los pines A4 y A5, se utilizaron estos pines porque son los que viene por defecto en Arduino uno R3 para SCL y SDA que son las conexiones de comunicación que salían del módulo I2C. La librería que se utilizó fue LiquidCrystal_I2C.
Seguimos por cómo implementar la navegación del menú con el módulo joystick en función de los valores que se obtenían. En este caso la conexión del switch que tenía el módulo joystick se conectó al pin 8 digital y se configuró como pin de entrada y a un valor alto, los pines de los ejes X e Y se conectaron a los pines A0 y A1 porque los valores que podrían tomar no son 0 ó 1 sino que están entre varios rangos y para poder controlarlos se necesitaba una señal analógica.
Problemas encontrados
El número de conexiones hacía la placa era muy elevado, esto, se subsano instalando un módulo i2c para el lcd y así minimizar el número de conexiones.
Apartado desarrollado por Alejandro Herrera González
Motor Paso a Paso y Driver
De esta parte se encargó Adrián Leonis García, pero cuando surgieron los problemas a la hora de combinar el módulo lcd y el motor paso a paso con el driver, buscamos una solución entre los tres integrantes del grupo ya que nos costó bastante poder encontrar el camino a la solución.
Una vez realizado estos dos pasos nos pusimos en marcha con el motor paso a paso y el driver controlador del mismo. Primero hicimos una demo para ver como funcionaba, una vez que entendimos como funcionaba hicimos la relación de pasos con los engranajes que teníamos, en este caso fue con prueba error hasta que se consiguió. Cuando quisimos juntos lo que teníamos realizado del lcd y el motor nos dimos cuenta que el módulo lcd empezaba a parpadear cuando giraba el motor. Esto nos llevó un tiempo darnos cuenta cómo solucionarlo y mucha búsqueda en internet. La solución que implementamos fue sacar el voltaje de la energía suministrada por el Arduino en este caso 9v y pasarlo por un regulador de voltaje que convirtiera de 9v a 5v necesarios para el driver del motor paso a paso.
Problemas encontrados
La tensión demandada era muy elevada para poder combinarlo con el lcd se solucionó este problema implementando un regulador de voltaje DC-DC el cual suministra la tensión al driver.
Módulo Bluetooth
Parte realizada por: Erik Fernández Orgaz.
Ahora ya solo nos quedaba el módulo bluetooth que tras una búsqueda exhaustiva por internet nos dimos cuenta que los comandos AT por los que se regía el módulo bluetooth no nos valía para la implementación que queríamos realizar. Encontramos un GitHub que podía flashear el módulo haciéndolo pasar de un hc-06 a módulo rn-42 de mejores prestaciones y con las funcionalidades que necesitábamos. Una vez llevado a cabo esta operación tuvimos el problema de cómo comunicarnos con el módulo, nos dimos cuenta que el módulo trabaja con 3.3 voltios el pin de recepción, esto se resolvió con un divisor de tensión con resistencias de 1k ohm y 2k ohm.
Problemas encontrados
Los comandos reconocidos por el módulo no eran suficiente para lo que necesitábamos, la solución fue flashear el módulo para que por firmware fuera un dispositivo rn-42 esto se llevó a cabo con la ayuda de un módulo ftdi-usb en el cual se soldaron los pines del módulo ftdi-usb RTS,RSD,RI y DTR a los pines CLK, MISO, MOSI y CSB del módulo bluetooth respectivamente de la siguiente forma:
Esto nos permitió poder iniciar una comunicación del dispositivo hc-06 al ordenador y con la utilización de las aplicaciones Bluesuite y Pstool se pudo llevar acabo el flasheo del dispositivo.
Una vez realizado este paso faltaba configurar el dispositivo para que simulara un teclado y poder utilizar la tecla «enter» para que hiciera una foto desde la aplicación nativa de la cámara del teléfono, esto se llevó a cabo con ayuda de la librería BPLib referenciada en la bibliografía de la presentación hecha.
Esquema general de conexiones
Código del Software
#include <LiquidCrystal_I2C.h> // RH - use this library for LCD displays with I2C backpack
#include <Stepper.h>
#include <SoftwareSerial.h>
const int SW_pin = 8; // digital pin connected to switch output
const int X_pin = A0; // analog pin connected to X output
const int Y_pin = A1; // analog pin connected to Y output
int bluetoothTx = 2; // TX-O pin of bluetooth mate, Arduino D2
int bluetoothRx = 3; // RX-I pin of bluetooth mate, Arduino D3
int MenuNr = 0; // Menu number
int PhotoNr = 2; // The amount of photos that have to be taken
bool Flag1 = 0; // This flag is only active during 1 program cycle (prevents constantly adding/subtracting 1 to the menu number when the joystick is pushed to the side)
bool Flag2 = 0; // This flag is only active during 1 program cycle (prevents constantly adding/subtracting 2 to the photo number when the joystick is pushed up or down)
bool Flag3 = 0; // This flag is only active during 1 program cycle (prevents constantly adding/subtracting 1 to the RPM when the joystick is pushed up or down)
bool Flag4 = 0; // This flag is only active during 1 program cycle (prevents constantly adding/subtracting 1 to the turn number when the joystick is pushed to the side)
bool Flag5 = 0; // This flag is only active during 1 program cycle (prevents constantly adding/subtracting 1 to the RPM when the joystick is pushed up or down)
bool Flag6 = 0; // This flag is only active during 1 program cycle to clear the lcd
int SwMenu = 0; // Switch menu (Sub menu's in the main menu's)
bool BtnFlag = 0; // This flag is only active during 1 program cycle (prevents constantly adding of 1 to SwMenu when button is pressed)
// RH - added variables for fast change & cancel modes
int FastChng = 0; // indicates fast change value mode. 0 = off, 1 = delay mode, 2 = fast changing mode
const unsigned long FastDelay = 1000; // delay mode time (before values change fast)
const unsigned long ShortInt = 100; // short fast change interval
const unsigned long LongInt = 300; // long fast change interval
const unsigned long BtnDelay = 2000; // delay for button press to cancel operations. Note this is an approximate delay, since stepper motor
// suspends all program execution until motor finishes its move
unsigned long SetTime = 0; // time value for fast change & button cancel modes. Used to calculate time intervals
bool BtnCancelFlag = 0; // This flag is used to detect when button is pressed for canceling operations
bool MaxSwMenu = 0; // This flag is used for detecting when the maximum SwMenu is reached
bool CinCancelFlag = 0; // This flag is used to trigger cinematic cancel. 1 = cancel cinematic operation
int StepPoll = 480; // number of motor steps to poll for cinematic cancel (at 15 rpm)
int Cntr = 0; // step counter for cinematic motor cancel
// RH - end of added variables
const int stepsPerRevolution = 2048; // change this to fit the number of steps per revolution
int FullRev = 14336; // 1 full revolution of the big gear -> Small-Big gear ratio is 7:1
int rolePerMinute = 15; // Adjustable range of 28BYJ-48 stepper is 0~17 rpm
int PhotoTaken = 0; // Amount of photo's that have been taken
int StepPerPhoto; // Amount of steps per photo (calculated -> see MenuNr 0/SwMenu 2)
int TurnNr = 1; // Amount of turns
int CurrentTurn = 0; // Stores current turn number
int Steps = 0; // Amount of individual steps the stepper motor has to turn
LiquidCrystal_I2C lcd(0x27, 16, 2); // RH - use this for I2C LCD. Assumes default address of 0x27
Stepper myStepper(stepsPerRevolution, 9, 11, 10, 12); // Use these pins for the stepper motor
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
void setup() {
bluetooth.begin(115200); // The Bluetooth Mate defaults to 115200bps
delay(100);
bluetooth.print("$$$");
delay(100);
bluetooth.println("C");
delay(100);
bluetooth.println("U,9600,N");
delay(100);
bluetooth.begin(9600);
lcd.init(); // RH - I2C LCD init command
lcd.backlight(); // RH - I2C LCD turn backlight on
pinMode(SW_pin, INPUT); //Set pushbutton as input
digitalWrite(SW_pin, HIGH); //Set SW_pin High
myStepper.setSpeed(rolePerMinute); //Set RPM of steppermotor
lcd.setCursor(4, 0); //Startup screen start
lcd.print("Welcome!"); // """"" //
lcd.setCursor(1, 1); // """"" //
lcd.print("Software: V1.6"); // """"" //
delay(3000); // """"" //
lcd.clear(); // """"" //
lcd.setCursor(0, 0); // """"" //
lcd.print("Designed by"); // """"" //
lcd.setCursor(0, 1); // """"" //
lcd.print("Erik,Alejandro,Adrian"); // """"" //
delay(2000); // """"" //
lcd.clear(); //Startup screen end
}
void loop() {
int XValue = analogRead(X_pin); // Read the analog value from The X-axis from the joystick
int YValue = analogRead(Y_pin); // Read the analog value from The Y-axis from the joystick
int SwValue = digitalRead(SW_pin); // Read the digital value from The Button from the joystick
if (MenuNr < 0){ //This sets the min number of menu's
MenuNr = 0;
}
else if ( MenuNr > 2){ //This sets the max numbers of menu's
MenuNr = 2;
}
if (XValue < 400 && Flag1 == 0 && SwMenu == 0){ //if the joystick is pushed to the right side and flag1 is 0 then 1 will be added to the menu number (purpose of the flag -> see comment Flags above)
MenuNr = MenuNr + 1;
Flag1 = 1;
lcd.clear();
}
if (XValue > 600 && Flag1 == 0 && SwMenu == 0){ //if the joystick is pushed to the left side and flag1 is 0 then 1 will be subtracted from the menu number (purpose of the flag -> see comment Flags above)
MenuNr = MenuNr - 1;
Flag1 = 1;
lcd.clear();
}
if (XValue > 399 && XValue < 599 && Flag1 == 1){ //if joystick is at neutral possition, flag1 is set to 0 (purpose of the flag -> see comment Flags above)
Flag1 = 0;
}
if (SwValue == 0 && BtnFlag == 0 && MaxSwMenu == 0){ //if the button is pressed and the flag is 0 -> add 1 to menu
SwMenu = SwMenu + 1;
BtnFlag = 1;
BtnCancelFlag = 0;
lcd.clear();
}
if (SwValue == 1 && BtnFlag == 1){ //if the button is not pressed and the flag is 0 -> Reset the flag (purpose of the flag -> see comment Flags above)
BtnFlag = 0;
}
switch (MenuNr){
case 0: //***********************************************Menu0***********************************************//
if (SwMenu == 0){ //Menu 0 selected
lcd.setCursor(3, 0);
lcd.print("Escaner");
lcd.setCursor(14,0);
lcd.print("->");
}
if (SwMenu == 1){ //entered menu 0
lcd.setCursor(0, 0);
lcd.print("Nr of photo's");
lcd.setCursor(7, 1);
lcd.print(PhotoNr);
if (FastChng == 0) { // RH - if not in fast change mode, update set time
SetTime = millis();
}
if (YValue < 400 && Flag2 == 0){ //joystick up -> Add 2 to number of photo's
PhotoNr = PhotoNr + 2;
Flag2 = 1;
FastChng = 1;
lcd.clear();
}
if (YValue > 600 && Flag2 == 0){ //joystick down -> Subtract 2 from number of photo's
PhotoNr = PhotoNr - 2;
Flag2 = 1;
FastChng = 1;
lcd.clear();
}
if (YValue > 399 && YValue < 599 && Flag2 == 1){ //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 2
Flag2 = 0;
FastChng = 0;
}
if (YValue < 400 && FastChng == 1) { // RH - if joystick up is held for > the fast delay time, then enter fast change mode
if ((millis() - SetTime) > FastDelay) {
FastChng = 2;
SetTime = millis(); // update the set time
}
}
if (YValue > 600 && FastChng == 1) { // RH - if joystick down is held for > the fast delay time, then enter fast change mode
if ((millis() - SetTime) > FastDelay) {
FastChng = 2;
SetTime = millis(); // update the set time
}
}
if (YValue < 400 && FastChng == 2) { // RH - we are in fast change mode, so we want to update the values quickly, proportional between
if ((millis() - SetTime) > (LongInt - (400 - YValue) * (LongInt - ShortInt) / 400)) { // ShortInt and LongInt based on joystick deflection
PhotoNr = PhotoNr + 2;
SetTime = millis();
lcd.clear();
}
}
if (YValue > 600 && FastChng == 2) { // RH - same for joystick down in fast change mode
if ((millis() - SetTime) > (LongInt - (YValue - 600) * (LongInt - ShortInt) / 400)) {
PhotoNr = PhotoNr - 2;
SetTime = millis();
lcd.clear();
}
}
if (PhotoNr < 2){ //Min allowable Nr of photo's
PhotoNr = 2;
}
if (PhotoNr > 200){ //Max allowable Nr of photo's
PhotoNr = 200;
}
}
if (SwMenu == 2){ //Program started
MaxSwMenu = 1;
lcd.setCursor(0, 0);
lcd.print("Program started");
lcd.setCursor(0, 1);
lcd.print("Photo Nr: ");
lcd.print(PhotoTaken);
StepPerPhoto = FullRev / PhotoNr; //Calculate amount of steps per photo
if (PhotoTaken < PhotoNr){
myStepper.setSpeed(rolePerMinute); //Set motor speed
myStepper.step(StepPerPhoto); //move the calculated amount of steps
PhotoTaken = PhotoTaken + 1; //Add 1 to photos taken
lcd.setCursor(0, 1);
lcd.print("Photo Nr: "); //Taking photo's
lcd.print(PhotoTaken);
delay(100);
bluetooth.println(); //Take a photo simulating press key enter
delay(10000);
}
if (PhotoTaken == PhotoNr){ //If the amount of photos taken is equal to the amount of photos that have to be taken -> Program finished
lcd.setCursor(0, 0);
lcd.print("Program finished");
delay(3000);
lcd.clear(); //Rest parameters
PhotoTaken = 0;
PhotoNr = 2;
SwMenu = 0;
MaxSwMenu = 0;
Steps = 0;
}
// RH NOTE - cancelling works but delay is longer than expected since stepper motor movement is blocking
if (SwValue == 0 && BtnCancelFlag == 0) { // if button is pressed, start timing for cancel
BtnCancelFlag = 1;
SetTime = millis();
}
if (SwValue == 1 && BtnCancelFlag == 1) { // RH - if button released before BtnDelay, then reset flag
BtnCancelFlag = 0;
}
if (SwValue == 0 && BtnCancelFlag == 1 && ((millis() - SetTime) > BtnDelay)) { // RH - button has been held for > BtnDelay, so cancel operation
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Program cancel");
delay(3000);
lcd.clear();
PhotoTaken = 0;
PhotoNr = 2;
SwMenu = 0;
MaxSwMenu = 0;
Steps = 0;
BtnCancelFlag = 0;
}
}
break;
case 1: //***********************************************Menu1***********************************************//
if (SwMenu == 0){ //Menu1 selected
lcd.setCursor(0,0);
lcd.print("<-");
lcd.setCursor(3, 0);
lcd.print("Cinematica");
lcd.setCursor(14,0);
lcd.print("->");
CinCancelFlag = 0;
Cntr = 0;
}
if (SwMenu == 1){ //Entered menu1 - sub menu1
lcd.setCursor(0, 0);
lcd.print("motor speed");
lcd.setCursor(7, 1);
lcd.print(rolePerMinute);
if (FastChng == 0) { // RH - if not in fast change mode, update set time
SetTime = millis();
}
if (YValue < 400 && Flag3 == 0){ // joystick up -> Add 1 RPM
rolePerMinute = rolePerMinute + 1;
Flag3 = 1;
FastChng = 1;
lcd.clear();
}
if (YValue > 600 && Flag3 == 0){ // joystick down -> Subtract 1 RPM
rolePerMinute = rolePerMinute - 1;
Flag3 = 1;
FastChng = 1;
lcd.clear();
}
if (YValue > 399 && YValue < 599 && Flag3 == 1){ //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 1
Flag3 = 0;
FastChng = 0;
}
if (YValue < 400 && FastChng == 1) { // RH - if joystick up is held for > the fast delay time, then enter fast change mode
if ((millis() - SetTime) > FastDelay) {
FastChng = 2;
SetTime = millis(); // update the set time
}
}
if (YValue > 600 && FastChng == 1) { // RH - if joystick down is held for > the fast delay time, then enter fast change mode
if ((millis() - SetTime) > FastDelay) {
FastChng = 2;
SetTime = millis(); // update the set time
}
}
if (YValue < 400 && FastChng == 2) { // RH - we are in fast change mode, so we want to update the values at the LongInt interval
if ((millis() - SetTime) > LongInt) { // (using fixed LongInt since not that many values to cycle through)
rolePerMinute = rolePerMinute + 1;
SetTime = millis();
lcd.clear();
}
}
if (YValue > 600 && FastChng == 2) { // RH - same for joystick down in fast change mode
if ((millis() - SetTime) > LongInt) {
rolePerMinute = rolePerMinute - 1;
SetTime = millis();
lcd.clear();
}
}
if (rolePerMinute < 1){ //Min allowable RPM
rolePerMinute = 1;
}
if (rolePerMinute > 17){ //Max allowable RPM
rolePerMinute = 17;
}
}
if (SwMenu == 2){ //Entered menu1 - sub menu2
lcd.setCursor(0, 0);
lcd.print("Nr of turns");
lcd.setCursor(7, 1);
lcd.print(TurnNr);
if (FastChng == 0) { // RH - if not in fast change mode, update set time
SetTime = millis();
}
if (YValue < 400 && Flag4 == 0){ // joystick up -> Add 1 turn
TurnNr = TurnNr + 1;
Flag4 = 1;
FastChng = 1;
lcd.clear();
}
if (YValue > 600 && Flag4 == 0){ // joystick down -> Subtract 1 turn
TurnNr = TurnNr - 1;
Flag4 = 1;
FastChng = 1;
lcd.clear();
}
if (YValue > 399 && YValue < 599 && Flag4 == 1){ //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 1
Flag4 = 0;
FastChng = 0;
}
if (YValue < 400 && FastChng == 1) { // RH - if joystick up is held for > the fast delay time, then enter fast change mode
if ((millis() - SetTime) > FastDelay) {
FastChng = 2;
SetTime = millis(); // update the set time
}
}
if (YValue > 600 && FastChng == 1) { // RH - if joystick down is held for > the fast delay time, then enter fast change mode
if ((millis() - SetTime) > FastDelay) {
FastChng = 2;
SetTime = millis(); // update the set time
}
}
if (YValue < 400 && FastChng == 2) { // RH - we are in fast change mode, so we want to update the values quickly, proportional between
if ((millis() - SetTime) > (LongInt - (400 - YValue) * (LongInt - ShortInt) / 400)) { // ShortInt and LongInt based on joystick deflection
TurnNr = TurnNr + 1;
SetTime = millis();
lcd.clear();
}
}
if (YValue > 600 && FastChng == 2) { // RH - same for joystick down in fast change mode
if ((millis() - SetTime) > (LongInt - (YValue - 600) * (LongInt - ShortInt) / 400)) {
TurnNr = TurnNr - 1;
SetTime = millis();
lcd.clear();
}
}
if (TurnNr < 1){ //Min allowable amount of turns
TurnNr = 1;
}
if (TurnNr > 200){ //Max allowable amount of turns
TurnNr = 200;
}
}
if (SwMenu == 3){ //Program started
MaxSwMenu = 1;
StepPoll = 32 * rolePerMinute; // RH - set polling rate StepPoll = number of steps per second (roughly)
lcd.setCursor(0, 0);
lcd.print("Program started");
lcd.setCursor(0, 1);
lcd.print("Turns done: ");
lcd.print(CurrentTurn);
if (CurrentTurn < TurnNr){
myStepper.setSpeed(rolePerMinute);
Cntr = 0; // RH - initialize step counter
while ((Cntr <= FullRev) && (CinCancelFlag == 0)) {
myStepper.step(StepPoll); // RH - breaking up plate rotation into roughly 1 sec intervals to check for cancel
Cntr = Cntr + StepPoll;
SwValue = digitalRead(SW_pin);
if (SwValue == 0 && BtnCancelFlag == 0) { // RH - check if button is pressed, if so start timing for cancel
BtnCancelFlag = 1;
SetTime = millis();
}
if (SwValue == 1 && BtnCancelFlag == 1) { // RH - if button released before BtnDelay, then reset button flag
BtnCancelFlag = 0;
}
if (SwValue == 0 && BtnCancelFlag == 1 && ((millis() - SetTime) > BtnDelay)) { // RH - button has been held for > BtnDelay, so cancel operation
CinCancelFlag = 1;
CurrentTurn = TurnNr;
}
}
if (CinCancelFlag == 0) { // RH - operation not cancelled, so continue
myStepper.step(FullRev + StepPoll - Cntr); // RH - need to move remainder of steps for 1 full turn due to kickout from while loop
CurrentTurn = CurrentTurn + 1;
lcd.setCursor(0, 1);
lcd.print("Turns done: ");
lcd.print(CurrentTurn);
}
}
if (CurrentTurn == TurnNr){ //If the current turn is equal to the amount of thurns that need to be turned -> program finished (RH - or cancelled)
lcd.setCursor(0, 0);
if (CinCancelFlag == 0) {
lcd.print("Program finished");
}
else {
lcd.clear();
lcd.print("Program cancel");
}
delay(3000);
lcd.clear(); //Reset
CurrentTurn = 0;
PhotoNr = 1;
rolePerMinute = 15;
SwMenu = 0;
MaxSwMenu = 0;
CinCancelFlag = 0;
Steps = 0;
}
}
break;
case 2: //***********************************************Menu2***********************************************//
if (SwMenu == 0){
lcd.setCursor(0,0);
lcd.print("<-");
lcd.setCursor(3, 0);
lcd.print("Manual");
lcd.setCursor(3,1);
lcd.print("control");
}
if (SwMenu == 1){ //Entered menu2
lcd.setCursor(0, 0);
lcd.print("motor speed");
lcd.setCursor(7, 1);
lcd.print(rolePerMinute);
if (FastChng == 0) { // RH - if not in fast change mode, update set time
SetTime = millis();
}
if (YValue < 400 && Flag5 == 0){ // joystick up -> Add 1 RPM
rolePerMinute = rolePerMinute + 1;
Flag5 = 1;
FastChng = 1;
lcd.clear();
}
if (YValue > 600 && Flag5 == 0){ // joystick down -> Subtract 1 RPM
rolePerMinute = rolePerMinute - 1;
Flag5 = 1;
FastChng = 1;
lcd.clear();
}
if (YValue > 399 && YValue < 599 && Flag5 == 1){ //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 1
Flag5 = 0;
FastChng = 0;
}
if (YValue < 400 && FastChng == 1) { // RH - if joystick up is held for > the fast delay time, then enter fast change mode
if ((millis() - SetTime) > FastDelay) {
FastChng = 2;
SetTime = millis(); // update the set time
}
}
if (YValue > 600 && FastChng == 1) { // RH - if joystick down is held for > the fast delay time, then enter fast change mode
if ((millis() - SetTime) > FastDelay) {
FastChng = 2;
SetTime = millis(); // update the set time
}
}
if (YValue < 400 && FastChng == 2) { // RH - we are in fast change mode, so we want to update the values at the LongInt interval
if ((millis() - SetTime) > LongInt) { // (using fixed LongInt since not that many values to cycle through)
rolePerMinute = rolePerMinute + 1;
SetTime = millis();
lcd.clear();
}
}
if (YValue > 600 && FastChng == 2) { // RH - same for joystick down in fast change mode
if ((millis() - SetTime) > LongInt) {
rolePerMinute = rolePerMinute - 1;
SetTime = millis();
lcd.clear();
}
}
if (rolePerMinute < 1){ //Min allowable RPM
rolePerMinute = 1;
}
if (rolePerMinute > 17){ //Max allowable RPM
rolePerMinute = 17;
}
if (XValue > 400 ){ //if the joystick is pushed to the right side and the neutral flag is 0 then 1 will be added to the menu number (purpose of the flag -> see comment Flag1 above)
Steps = Steps + 1;
myStepper.setSpeed(rolePerMinute);
myStepper.step(Steps);
lcd.setCursor(14, 1);
lcd.print("<-");
Flag6 = 1;
}
if (XValue < 600 ){ //if the joystick is pushed to the left side and the neutral flag is 0 then 1 will be subtracted from the menu number (purpose of the flag -> see comment Flag1 above)
Steps = Steps + 1;
myStepper.setSpeed(rolePerMinute);
myStepper.step(-Steps);
lcd.setCursor(0, 1);
lcd.print("->");
Flag6 = 1;
}
if (XValue > 399 && XValue < 599){ //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 1
Steps = 0;
if (Flag6 == 1){
lcd.clear();
Flag6 = 0; //This flag is only active during 1 program cycle to clear the lcd
}
}
}
if (SwMenu == 2){ //Leave menu 2 when button is pressed
lcd.clear();
CurrentTurn = 0;
PhotoNr = 1;
rolePerMinute = 15;
SwMenu = 0;
Steps = 0;
}
break;
default:
break;
}
}
Limitaciones
- El modelo 3D final conlleva un nivel de comprensión de modelaje 3D elevado junto con acceso a aplicaciones externas de la calidad requerida para el proceso.
- Podría haber una futura implementación en la cual automatizáramos la grabación del vídeo.
- La única compatibilidad es con dispositivos Android.
- El tamaño y peso de los objetos es limitado debido a que nuestro modelo es «casero».
Reparto de tareas
La implementación hardware de todo el conjunto se encargó Erik Fernández Orgaz, de la creación del PowerPoint de presentación Adrián Leonis García y de la creación de esta Memoria Alejandro Herrera González.
Presupuesto
Componentes | Precio |
Módulo LCD 16×2 con módulo I2C | 6 € |
Motor paso a paso | 0 € |
Driver | 0 € |
Módulo Bluetooth hc-06 | 10 € |
Regulador de voltaje | 5 € |
Módulo FTDI-USB | 5 € |
Piezas impresas en 3D | 0 € |
TOTAL | 26 € |
Vídeos de los Casos de Uso
Funcionalidad del Modo Escáner
Funcionalidad del Modo Cinemática
Funcionalidad del Modo de Control Manual
Vídeo Explicativo «Scan-It»
Material Extra
Vídeo de la presentación PowerPoint de apoyo
Bibliografía
https://www.youtube.com/watch?v=y8PcNbAA6AQ (Flash Hc-06)
https://github.com/lorf/csr-spi-ftdi (Software para Flash)
https://github.com/witnessmenow/BPLib (Comandos de configuración RN-42)