Wii Nunchuck Arduino vattenpass (6 / 7 steg)
Steg 6: Wii_Nunchuck_Level Arduino skiss belastning
Det finns två Arduino skisser: 1) Wiichuck_range_test; och 2) Wii_Nunchuck_Level.Du behöver först och främst veta vad Nunchuck accelerometerns varje axel dataområde är. Jag har testat några av dem och alla av dem visar små skillnader. Men mestadels, spänner är 60-70 som minimum och 180-200 som maximum. För bästa känslighet av nivån behöver du ladda Wiichuck_range_test först och hitta dessa värden (minimum, center (på nivå) och maximum) för varje axel och justera värdena i den huvudsakliga skissen om det behövs.
Rad test skissen är enkelt och rakt framåt så jag kommer inte att förklara i detalj här.
Huvudprogrammet, Wii_Nunchuck_Level visas nedan samt också bifogas.
Funktionen getData() få värdena för varje axel och lagra dem i byte array AgCl [] och hitta orientering på nivån och returnerar "orient."
Funktion orientation() få nuvarande axelvärdena och hitta orientering på nivån. Varje inriktning ger två axlar som mitten (planat, runt 120-130) och en axel som minimum eller maximum beroende på allvar. Använder detta kännetecken, bestämmer det orienteringen.
Den huvudsakliga loop() är ganska enkel. Det övervakar om kalibrering knappen trycks genom att se om stift 10 är hög och i övrigt den läsa aktuella data och vända på lysdioder. Programmet jämför nuvarande data till den lagrade (i EEPROM av ATmega328P) kalibreringsdata. Det finns tre stadier av visning: 1) om värdet är inom vissa intervall, det kommer att vända på den centrala röd lysdiod ansluten till det digitala stiftet 7; 2) om värdet är större än intervallet (sens i programmet) och mindre än 2 gånger av spänna (sens), det kommer att vända på röda LED och en grön LED på motsatsen (för att simulera bubbla riktning) sida av tilt; 3) om värdet är större än 2 gånger av spänna (sens), är sedan endast den gröna lysdioden aktiverat.
Värdena som kalibrering är neutral värdet av varje axel läsa när det är planat på axeln. Till exempel den Nunchuck data behandlingen är mellan 60-70 (dessa värden är olika från sensorn till sensor) på -g (upp och ner) på axeln och är över 170 g (upp till höger). Så neutral (planat) värdet av varje axel om 120-130. Kalibreringen börjar när stift 10 går högt anslutna till V + med en liten tryckknapp switch tryckte. En kalibreringsprocessen börjar, för att ge användaren lite tid för att sätta enheten på en plan yta, väntar den tills den centrala röda lysdioden blinkar några gånger. Den faktiska kalibreringen sker verkligen snabbt och följt av några snabbare blinkar.
/*
* Wii_Nunchuck_Level
* Feb-Mar 2012, Jinseok Jeon
* http://jeonlab.wordpress.com
*
* Wii Nunchuck data läses:
* nunchuck_funcs.h från WiiChuckDemo av Tod E. Kurt,
* http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available/
*/
#include < Wire.h >
#include < EEPROM.h >
#include "nunchuck_funcs.h"
byte AgCl [3]. Accelerometer avläsningar för x, y, z-axel
int calPin = 10; kalibrering pin
int sens = 1; känslighet
int orient;
void setup()
{
nunchuck_init();
för (int jag = 5; jag < 10; i ++) {
pinMode (i, matas);
} //9 vänster, 8 upp, 7 center, 6 ner, 5 rätt
pinMode (calPin, ingång);
Delay(100);
}
void loop()
{
om kalibrering pinnen trycks ner, hoppa till funcion calibrate()
om (digitalRead(calPin) == hög) calibrate();
getData();
om (orientera == 1 || orientera == 2) {
om (abs (AgCl [0]-EEPROM.read (0 + orient * 10)) < = 2 * sens) digitalWrite (7, hög).
om (AgCl [0]-EEPROM.read (0 + orient * 10) > sens) digitalWrite (5, hög).
om (EEPROM.read(0 + orient*10)-AgCl [0] > sens) digitalWrite (9, hög).
}
om (orientera == 3 || orientera == 4) {
om (abs (AgCl [1]-EEPROM.read (1 + orient * 10)) < = 2 * sens) digitalWrite (7, hög).
om (AgCl [1]-EEPROM.read (1 + orient * 10) > sens) digitalWrite (8, hög).
om (EEPROM.read(1 + orient*10)-AgCl [1] > sens) digitalWrite (6, hög).
}
om (orientera == 5 || orientera == 6) {
om (abs (AgCl [0]-EEPROM.read (0 + orient * 10)) < = 2 * sens & & abs (AgCl [1]-EEPROM.read (1 + orient * 10)) < = 2 * sens) digitalWrite (7, hög).
om (AgCl [0]-EEPROM.read (0 + orient * 10) > sens) digitalWrite (5, hög).
om (EEPROM.read(0 + orient*10)-AgCl [0] > sens) digitalWrite (9, hög).
om (AgCl [1]-EEPROM.read (1 + orient * 10) > sens) digitalWrite (8, hög).
om (EEPROM.read(1 + orient*10)-AgCl [1] > sens) digitalWrite (6, hög).
}
Delay(50);
för (int jag = 5; jag < 10; i ++) {//turn av alla lysdioder
digitalWrite (i, låg);
}
}
void getData()
{
nunchuck_get_data();
AgCl [0] = nunchuck_accelx();
AgCl [1] = nunchuck_accely();
AgCl [2] = nunchuck_accelz();
Orient = orientation(); få orientering
}
void calibrate()
{
för (int jag = 0; jag < 3; i ++) {
digitalWrite (7, hög).
Delay(500);
digitalWrite (7, låg).
Delay(500);
}
getData();
för (int jag = 0; jag < 3; i ++) {
EEPROM.write (i + orient * 10, accl[i]);
}
för (int jag = 0; jag < 3; i ++) {
digitalWrite (7, hög).
Delay(200);
digitalWrite (7, låg).
Delay(200);
}
}
int orientation()
{
om (AgCl [0] > 125 & & AgCl [0] < 145 & & AgCl [2] > 110 & & AgCl [2] < 140) {
om (AgCl [1] > 170) orientera = 1; längst ner på golvet
annars om (AgCl [1] < 75) orientera = 2; Top på golvet
}
annars om (AgCl [1] > 110 & & AgCl [1] < 140 & & AgCl [2] > 110 & & AgCl [2] < 140) {
om (AgCl [0] > 180) orientera = 3; kvar på golvet
annars om (AgCl [0] < 90) orientera = 4. mitt på golvet
}
annars om (AgCl [1] > 110 & & AgCl [1] < 140 & & AgCl [0] > 125 & & AgCl [0] < 145) {
om (AgCl [2] > 170) orientera = 5. tillbaka på golvet
annars om (AgCl [2] < 80) orientera = 6. framsidan på golvet
}
returnera orient;
}