Étape 8: I2C LCD Interface et Menu
Il existe de nombreuses façons de coder l’interface utilisateur et le menu à l’aide d’un bouclier Arduino et LCD. Notre bouclier a 2 lignes d’affichage de 16 caractères chacune, quatre touches directionnelles, un bouton destiné à être une fonction « select » et un bouton reset. Pour simplifier le processus de codage, nous seulement utilisé les quatre touches directionnelles, faite d’une structure de boucle if plutôt brut et utiliser des variables d’instance pour beaucoup de choses. Pour ceux plus à l’aise avec C++, nous vous suggérons d’utiliser une structure de données (comme suggéré ici) ou quelque chose de plus élégant que trop nombreux-if-boucles. Nous voulions l’utilisateur de statistiques d’accès enregistré telles que le dépaysement pédalé en une seule fois, le total "éloigné" pédalé sur cette moto et les Watt-heures totales générés depuis le premier jour. Alors que l’utilisateur les pédales, nous voulons l’écran pour afficher des statistiques telles que le temps puisque l’utilisateur commencé à pédaler, vitesse en kilomètres par heure (km étant un fermeur appréciée aux États-Unis), en cours de génération de puissance, watts-heure générée au cours de la période de cyclisme. Pour les lecteurs qui n’ont pas utilisé un bouclier I2C LCD avant, ici est un bon point de départ.
Les calculs de ces statistiques n’étaient pas difficiles ; en tr/min et km/s, nous avons divisé le nombre de cycles pédalé au moment où il a fallu pour l’utilisateur que pédaler plusieurs cycles et convertie les unités. Nous avons mesuré le rayon de la roue arrière de notre moto et trouvé le rayon à 28 cm. Ainsi la circonférence est de 175,929 cm, de miles 0.00109317 ou de 0.00175929km. Nous avons calculé la distance fait du vélo à l’aide de distance = taux * temps. Pour la puissance générée, puissance = courant * tension (P = IV). Pour obtenir un WH généré, nous avons effectué une addition de type Riemann-somme en multipliant la puissance instantanée au moment où passé (0,5 seconde), et ajoutant que toutes les demi-secondes l’utilisateur a pédalé.
En ce qui concerne le menu, nous avons indexé chaque écran et un mannequin comptage variable permettant de naviguer dans les écrans. Haut et en bas se soustraire ou ajouter à la variable, tandis que la gauche nous ramène au menu hiérarchisé supérieur et droite nous emmène dans les sous-menus.
Voici une représentation schématique de notre menu
Menu racine
> dépaysement
>> Voir la valeur
> total distance parcourue
>> Voir la valeur
> toute l’électricité
>> Voir la valeur
> a propos
>> toutes les informations il y a sur le vélo.
le code complet se trouve à la fin de ce Instructable
le code en gras , c’est ce que nous ajoutons au code d’en haut
inclure le code de bibliothèque :
#include < Wire.h >
#include < Adafruit_MCP23017.h >
#include < Adafruit_RGBLCDShield.h >
#include < EEPROM.h > //for de stockage à long terme de l’information sur Arduinos
Cette partie se mot pour mot du tutoriel de Adafruit qui nous lien ci-dessus
Le bouclier utilise les broches I2C SCL et SDA. Sur Arduinos classique
C’est analogique 4 et 5, vous ne pouvez pas utiliser ceux pour analogRead() plus
Toutefois, vous pouvez connecter d’autres capteurs I2C au bus I2C et de partager
le bus I2C. Lcd Adafruit_RGBLCDShield = Adafruit_RGBLCDShield() ;
Ces #defines le rendent facile définir la couleur du rétro-éclairage
#define rouge 0 x 1
#define jaune 0 x 3
#define vert 0 x 2
#define TEAL 0 x 6
#define bleu 0 x 4
#define VIOLET 0 x 5
#define blanc 0 x 7
ici commence la partie que nous avons codés
ptr int = 0 ; pointeur de menu
int minutes, secondes, kmh ;
variables de stockage à long terme
int timeAddress = 0 ;
int distanceAddress = 1 ;
int powerAddress = 2 ;
timeValue octet, distanceValue, powerValue ;
Boolean isHome = true ;
void setup() {}
LCD.Begin (16, 2) ;
LCD.Print ("Hello, world!") ;
lcd.setBacklight(WHITE) ;
timeValue = EEPROM.read(timeAddress) ;
distanceValue = EEPROM.read(distanceAddress) ;
powerValue = EEPROM.read(powerAddress) ;
root() ; Set d’affichage au menu racine
}
uint8_t i = 0; Nous mettons cela étant donné que le tutoriel inclus (pas exactement ce que c’est pour)
void loop() {}
menuFunction() ; voir si le bouton est enfoncé
Si (motorV > 1.0 & &! hasBeenOn) {}
LCD.Clear() ;
lcd.setCursor(0,0) ;
LCD.Print ("échauffement...") ;
lcd.setCursor(0,1) ;
LCD.Print (« Gardez pédaler.") ;
lcd.setBacklight(GREEN) ;
digitalWrite (cc haute) ; Appuyez sur start sur le contrôleur de charge
lcd.setBacklight(YELLOW) ;
Delay(3500) ; Appuyez sur start pendant 3,5 secondes
cycle = 0 ;
T0 = millis() ;
digitalWrite (cc faible) ; cesse d’appuyer sur start
devrait maintenant être recharge de la batterie
LCD.Clear() ;
lcd.setCursor(0,0) ;
hasBeenOn = true ;
LCD.Print ("charge batterie") ;
lcd.setBacklight(RED) ;
lcd.setCursor (3, 1) ;
timeOn = millis() ;
moment de combien de temps la personne a été pédaler
LCD.Print((Millis()-timeOn)/1000) ;
Delay(Wait) ;
isHome = false ;
}
ElseIf (motorV > 1.0 & & hasBeenOn) {}
secondes = int((millis()-timeOn)/1000) ;
mn = int(secs/60) ;
secondes = int(secs%60) ; Cela pourrait aussi être écrite comme une fonction séparée
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print(mins) ;
lcd.setCursor (2, 0) ;
imprimer le nombre de secondes depuis le départ vélo
LCD.Print(":") ;
lcd.setCursor (3, 0) ;
LCD.Print(secs) ;
lcd.setCursor (9, 1) ;
LCD.Print(RPM) ;
lcd.setCursor(13,1) ;
LCD.Print("RPM") ;
isHome = false ;
getCurrent() ; Cette impressions W, Wh
getkmh() ; Ceci affiche km/h
}
else {}
Si (timeValue > (millis()-timeOn/1000/60)) {}
timeValue = int(millis()-timeOn/1000/60) ;
EEPROM.write (timeAddress, timeValue) ;
}
{if(!isHome)}
root() ;
}
}
}
void getkmh() {}
kmh = tr/min * 60,0 * révolution ;
lcd.setCursor (0, 1) ;
LCD.Print(kmh) ;
lcd.setCursor(2,1) ;
LCD.Print ("km/h") ;
}
getCurrent() Sub {}
courant = (float(analogRead(hall))-514.5) / 26,5 ;
lcd.setCursor (6, 0) ;
LCD.Print (int (courant * 13)) ;
lcd.setCursor(8,0) ;
LCD.Print("W") ;
WH = Wh + float /3600.0*current*13.0 (attendre) ;
lcd.setCursor(10,0) ;
LCD.Print(WH) ;
lcd.setCursor(13,0) ;
LCD.Print("WH") ;
}
void menuFunction() {}
Delay(200) ;
boutons d’uint8_t = lcd.readButtons() ;
Si {(boutons)
Si (boutons & BUTTON_UP) {}
scrollUp(ptr) ;
}
Si (boutons & BUTTON_DOWN) {}
if(ptr >0) {}
scrollDown(ptr) ;
}
}
Si (boutons & BUTTON_LEFT) {}
Si (ptr > = 1 & & ptr < = 4) {}
root() ;
}
ElseIf (ptr > = 5) {}
menu() ;
}
}
Si (boutons & BUTTON_RIGHT) {}
scrollRight() ;
}
}
}
menu() Sub {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("MENU (défilement V)") ;
lcd.setCursor (0, 1) ;
LCD.Print ("Top times") ;
ptr = 1 ;
}
root() Sub {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("Bike à Charge!") ;
lcd.setCursor (0, 1) ;
LCD.Print ("Menu (droit >)") ;
ptr = 0 ;
isHome = true ;
}
void scrollRight() {}
Serial.println(PTR) ;
if(PTR == 0) {}
menu() ;
}
d’autre if(ptr == 1) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("meilleur temps") ;
lcd.setCursor (0, 1) ;
LCD.Print(TimeValue) ; RAPPELER LE NUMÉRO!!! MEILLEUR TEMPS
lcd.setCursor(13,1) ;
LCD.Print("min") ;
ptr = 5 ;
}
d’autre if(ptr == 2) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("distance totale") ;
lcd.setCursor (0, 1) ;
LCD.Print(distanceValue) ; RAPPELER LE NUMÉRO!!! DISTANCE TOTALE
lcd.setCursor(14,1) ;
LCD.Print("mi") ;
ptr = 6 ;
}
d’autre if(ptr == 3) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("énergie totale") ;
lcd.setCursor (0, 1) ;
LCD.Print(powerValue) ; RAPPELER LE NUMÉRO!!! WATTHEURES TOTAL
lcd.setCursor(15,1) ;
LCD.Print("J") ;
ptr = 7 ;
}
d’autre if(ptr == 4) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("Scroll down to") ;
lcd.setCursor (0, 1) ;
LCD.Print ("lire la suite!!! (V)"); RAPPELER LE NUMÉRO!!! WATTHEURES TOTAL
ptr = 8 ;
}
}
void scrollDown(int i) {}
Serial.println(i) ;
Si (j’ai == 1) {}
lcd.setCursor (0, 1) ;
LCD.Print ("distance totale") ;
ptr = 2 ;
}
else if (i == 2) {}
lcd.setCursor (0, 1) ;
LCD.Print ("énergie totale") ;
ptr = 3 ;
}
else if (i == 3) {}
lcd.setCursor (0, 1) ;
LCD.Print ("a propos!") ;
ptr = 4 ;
}
else if (i == 8) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("vélo électronique ») ;
lcd.setCursor (0, 1) ;
LCD.Print ("travaillé sur par:") ;
ptr = 9 ;
}
else if (i == 9) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("a. McKay 13") ;
lcd.setCursor (0, 1) ;
LCD.Print (« J. Wong 15") ;
ptr = 10 ;
}
else if (i == 10) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print("A.Karapetrova'15") ;
lcd.setCursor (0, 1) ;
LCD.Print (« S. Walecka 15 ") ;
ptr = 11 ;
}
else if (i == 11) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print (« S. Li 17") ;
lcd.setCursor (0, 1) ;
LCD.Print (« N. Sandford 17") ;
ptr = 12 ;
}
else if (i == 12) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("For His Majesty") ;
lcd.setCursor (0, 1) ;
LCD.Print ("Dwight Whitaker") ;
ptr = 13 ;
}
else if (i == 13) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("Phys 128 ») ;
lcd.setCursor (0, 1) ;
LCD.Print ("Pomona College") ;
ptr = 14 ;
}
else if (i == 14) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("payé par le") ;
lcd.setCursor (0, 1) ;
LCD.Print ("SIO et Dept of") ;
ptr = 15 ;
}
else if (i == 15) {}
LCD.Clear() ;
lcd.setCursor (0, 0) ;
LCD.Print ("physique et") ;
lcd.setCursor (0, 1) ;
LCD.Print ("astronomie.") ;
ptr = 16 ;
}
}
void scrollUp(int i) {}
Si (j’ai == 2) {}
menu() ;
}
Si (j’ai > 2) {}
scrollDown(i-2) ;
}
}