Force Feedback med LCD-skärm (2 / 4 steg)
Steg 2: Ansluta till MegaMoto
Först måste vi tråd MegaMoto. Gör följande:
-Anslut din 12V utbudet till BAT +/-terminaler
-Anslut manöverdonet till MOTA och MOTB terminalerna
-VALFRIA Anslut BAT + till Vin om du vill driva Arduino från datorn, eller lämna USB inkopplad.
-Ställ MegaMoto stiften enligt följande:
-Aktiverar = 13
-PWMA = 11
-PWMB = 3
-Sensor = A5
Den vänstra knappen bör göra manöverdonet förlänga, högerknappen bör göra manöverdonet tillbaka. Om dina anvisningar återförs, sedan vända de MOTA och MOTB anslutningarna.
Nu när knapparna är konfigurerade kan vi lägga till LCD programmet resten av programmet. Vi har lagt till fyra nya funktioner. Read_LCD_buttons(), updateTrip(), updateLCD() och printFeedback().
Read_LCD_buttons() är samma som testprogrammet, det läser status för knapparna från LCD-skärmen.
UpdateTrip() används för att kontrollera resultaten av upp och ner knappar och ändra amp gränsen för att resa den säkerhet avstängningen på.
UpdateLCD() är det allmänna LCD skriver funktion, som skriver all ny information till LCD-skärmen.
PrintFeedback() skriver nuvarande strömstyrka lottningen till LCD-skärmen. Detta är separat från den huvudsakliga updateLCD() funktionen, så att vi kan se nuvarande dragningen i realtid, snarare än väntar på att slinga.
Ladda upp programmet för att testa är, i nästa steg kommer vi att gå över olika delar av koden i detalj.
Obs: Resa gränser och nuvarande feedback är inte faktiskt hur många ampere som dras, de är endast resultat av den nuvarande sensorn. Du kan lägga till en ekvation i konvertera värdet till ampere innan du skriver det till LCD-skärmen.
/ * Kod för att visa den aktuella amp dra av manöverdonet och att minska makten om det
stiger över en viss summa.
Skrivet av progressiva automatiseringar
16 juli 2015
Hårdvara:
-RobotPower MegaMoto kontroll styrelser
-LCD sköld
-Arduino Uno
*/
#include < LiquidCrystal.h >
LiquidCrystal lcd (8, 9, 4, 5, 6, 7); / / Välj stiften används på LCD-panelen
definiera vissa värden används av panel och knappar
#define btnRIGHT 1
#define btnUP 2
#define btnDOWN 3
#define btnLEFT 4
#define btnSELECT 5
#define btnNONE 0
int lcd_key = 0;
int adc_key_in = 0; //value att läsa LCD-knappen input
CONST int btnup = 130;
CONST int btndown = 306;
CONST int btnleft = 479;
CONST int btnright = 0;
CONST int Välj = 720;
CONST int ingen = 1023;
CONST int tröskel = 2; //Analog värden för LCD knappar
CONST int EnablePin = 13.
CONST int PWMPinA = 11;
CONST int PWMPinB = 3; stift för Megamoto
CONST int CPin1 = A5; motoriska feedback
int knappen = 0; //value att läsa LCD knappar
int leftlatch = låg;
int rightlatch = låg, //motor lås
int hitLimits = 0;
int hitLimitsmaxfront = 10;
int hitLimitsmaxback = 5; //values veta om resor gränsen var nådd
lång lastfeedbacktime = 0;
int firstfeedbacktimedelay = 750; första dröjsmål att ignorera nuvarande spike
int feedbacktimedelay = 50; fördröjning mellan feedback cykler
lång currentTimefeedback = 0;
int debounceTime = 500. belopp till Dämpningstid
lång lastButtonpress = 0; timer för debouncing
lång currentTimedebounce = 0;
int CRaw = 0; RAW A/D-värde
int maxAmps = 0; resa gränsen
lång currentTimetrip = 0;
lång SenasteUppdatering = 0;
int updateTime = 100; //how snabbt kan resa värden uppdatering
bool dontExtend = false;
bool firstRun = true; //program logik
char * titeln [] = {"progressiva", "AUTOMATIK"}; Makt på titel
void setup()
{
Serial.BEGIN(9600);
pinMode (EnablePin, OUTPUT);
pinMode (PWMPinA, OUTPUT);
pinMode (PWMPinB, OUTPUT); //Set motor utgångar
pinMode (CPin1, indata); //set feedback input
LCD.BEGIN (16, 2); / / start biblioteket
lcd.setCursor (0, 0), lcd.print(title[0]), lcd.setCursor (0, 1), lcd.print(title[1]); Skriv ut rubrik
fördröjning (2000), //show titel i 2 sekunder
currentTimetrip = millis();
currentTimedebounce = millis();
currentTimefeedback = 0; //Set första gånger
lcd.setCursor (0, 0);
LCD.Print ("ampere Feedback"); skriva ut menyn meddelande
updateLCD(); skriva nya värden till skärmen
} //end setup
void loop()
{
Serial.println ("Main loop");
updateTrip (); //check knappar, uppdatering strömstyrka
latchButtons (); //check knappar, se om vi behöver flytta
moveMotor (); //check lås, flytta motor in eller ut
} //end huvudloop
void updateLCD()
{
lcd.setCursor (0, 1);
LCD.Print ("ampere: 0");
lcd.setCursor (8, 1);
LCD.Print ("resa: 0");
lcd.setCursor (13, 1);
LCD.Print(""), //clear gamla värde
om (maxAmps > 99) lcd.setCursor (13, 1);
annars om (maxAmps > 9) lcd.setCursor (14, 1);
annat lcd.setCursor (15, 1);
LCD.Print (maxAmps), //write nya värde
} //end updateLCD
void latchButtons()
{
knappen = read_LCD_buttons();
om (knappen == btnLEFT & & rightlatch! = hög) //left är framåt
{
currentTimedebounce = millis() - lastButtonpress;
om (currentTimedebounce > debounceTime & & dontExtend == false) //once du har utlöst dontExtend, ignorera alla framlänges pressar
{
leftlatch =! leftlatch;
knappen = btnNONE;
firstRun = sant;
lastButtonpress = millis();
hemkomst.
} //end om
} //end btnLEFT
om (knappen == btnRIGHT & & leftlatch! = hög) //right är tillbaka
{
currentTimedebounce = millis() - lastButtonpress;
om (currentTimedebounce > debounceTime)
{
rightlatch =! rightlatch;
knappen = btnNONE;
firstRun = sant;
lastButtonpress = millis();
hemkomst.
} //end om
} //end btnRIGHT
} //end latchButtons
int read_LCD_buttons()
{
adc_key_in = analogRead(A0); läsa värdet från sensorn
Delay(20);
om (adc_key_in > ingen - tröskeln & & adc_key_in < ingen + tröskel) återvända btnNONE;
om (adc_key_in > btnup - tröskeln & & adc_key_in < btnup + tröskel) återvända btnUP;
om (adc_key_in > btndown - tröskeln & & adc_key_in < btndown + tröskel) återvända btnDOWN;
om (adc_key_in > btnleft - tröskeln & & adc_key_in < btnleft + tröskel) återvända btnLEFT;
om (adc_key_in > btnright - tröskeln & & adc_key_in < btnright + tröskel) återvända btnRIGHT;
om (adc_key_in > Välj - tröskeln & & adc_key_in < Välj + tröskel) återvända btnSELECT;
återvända btnNONE; När alla andra misslyckas, återvända ingen
} //end readLCD
void updateTrip()
{
om (knappen == btnUP)
{
currentTimetrip = millis() - SenasteUppdatering;
om (currentTimetrip > updateTime)
{
maxAmps = maxAmps + 1.
om (maxAmps > 999) maxAmps = 0; //check för rollover
lcd.setCursor (13, 1);
LCD.Print(""), //clear gamla värde
om (maxAmps > 99) lcd.setCursor (13, 1);
annars om (maxAmps > 9) lcd.setCursor (14, 1);
annat lcd.setCursor (15, 1); //set markören följaktligen
LCD.Print (maxAmps), //write nya värde
SenasteUppdatering = millis();
} //end om
} //end om btnUP
annars om (knappen == btnDOWN)
{
currentTimetrip = millis() - SenasteUppdatering;
om (currentTimetrip > updateTime)
{
maxAmps = maxAmps - 1;
om (maxAmps < 0) maxAmps = 999; //check för rollover
lcd.setCursor (13, 1);
LCD.Print(""), //clear gamla värde
om (maxAmps > 99) lcd.setCursor (13, 1);
annars om (maxAmps > 9) lcd.setCursor (14, 1);
annat lcd.setCursor (15, 1); //set markören följaktligen
LCD.Print (maxAmps), //write nya värde
SenasteUppdatering = millis();
} //end om
} //end annars om btnDOWN
} //end updateTrip
void moveMotor()
{
om (leftlatch == hög) motorForward(255); hastighet = 0-255
om (leftlatch == låg) motorStop();
om (rightlatch == hög) motorBack(255); hastighet = 0-255
om (rightlatch == låg) motorStop();
} //end moveMotor
void motorForward(int speeed)
{
medan (dontExtend == false & & leftlatch == hög)
{
Serial.println ("flytta framåt");
digitalWrite (EnablePin, hög);
analogWrite (PWMPinA, speeed);
analogWrite (PWMPinB, 0); //move motor
om (firstRun == true) delay(firstfeedbacktimedelay);
annat delay(feedbacktimedelay); liten fördröjning att få snabba
getFeedback();
firstRun = false;
latchButtons();
} //end medan
} //end motorForward
void motorBack (int speeed)
{
medan (rightlatch == hög)
{
Serial.println ("flytta tillbaka");
digitalWrite (EnablePin, hög);
analogWrite (PWMPinA, 0);
analogWrite (PWMPinB, speeed); //move motor
Delay(3); liten fördröjning att få snabba
currentTimefeedback = millis() - lastfeedbacktime;
om (firstRun == true & & currentTimefeedback > firstfeedbacktimedelay) getFeedback(); om det inte har varit tillräckligt länge, händer ingenting
om (firstRun == false & & currentTimefeedback > feedbacktimedelay) getFeedback(); om det inte har varit tillräckligt länge, händer ingenting
firstRun = false;
latchButtons();
} //end medan
dontExtend = false;
} //end motorBack
void motorStop()
{
analogWrite (PWMPinA, 0);
analogWrite (PWMPinB, 0);
digitalWrite (EnablePin, låg);
firstRun = sant; //once motorn har stannat, återaktivera firstRun för start nuvarande spikar
} //end stopMotor
void getFeedback()
{
CRaw = analogRead(CPin1);
om (CRaw == 0 & & hitLimits < hitLimitsmaxback) hitLimits = hitLimits + 1.
annars om (CRaw == 0 & & hitLimits < hitLimitsmaxfront) hitLimits = hitLimits + 1.
annat hitLimits = 0;
om (hitLimits == hitLimitsmaxback)
{
rightlatch = låg;
} //end om
om (hitLimits == hitLimitsmaxfront)
{
leftlatch = låg;
hitLimits = 0;
} //end om
om (CRaw > maxAmps)
{
dontExtend = sant;
leftlatch = låg;
} //end om
printFeedback();
lastfeedbacktime = millis (); //store tidigare tid för att ta emot feedback
} //end getFeedback
void printFeedback()
{
lcd.setCursor (5, 1);
LCD.Print("");
om (CRaw > 99) lcd.setCursor (5, 1);
annars om (CRaw > 9) lcd.setCursor (6, 1);
annat lcd.setCursor (7, 1);
LCD.Print(CRaw);
} //end printFeedback