Stap 4: Componeren een Arduino Sketch
Hieronder is de code die ik gebruikt om mijn controlesysteem.
Ik ben met behulp van verschillende bibliotheken om het gebruik van de IR ontvanger, LCD-scherm over de I2C en de servo.
De meeste van mijn variabelen worden gedefinieerd binnen de functies die ze gebruiken, maar we moeten de pin ontvangen voor de IR ontvanger definiëren zodat we de IR ontvanger object kunt instantiëren. Ook moeten we instantiëren de resultaten van de IR ontvanger en de servo en LCD-display.
De setup-functie begint met de seriële monitor starten en het initialiseren van het LCD-scherm en het inschakelen van de achtergrondverlichting. Tijdens de installatie moeten ook beginnen de IR ontvanger hechten de servo pin nummer 9 te definiëren pin 6 en 7 als uitgangen voor de motor en de estafette.
De hoofdlus roept enkel drie functies die hieronder worden beschreven
/*************************************************************************************** Control System Program for a simple Arduino based Drag Reduction System By Korey Prince This program turns a relay on and off using an IR remote and detects the speed of a motor to determine when to actuate a wing based on the input of a potentiometer ***************************************************************************************/ //include all libraries used in this program #include <irremote.h> #include <liquidcrystal_i2c.h> #include <wire.h> #include <servo.h> int RECV_PIN = 11;//define IR recieve as pin 11 IRrecv irrecv(RECV_PIN);//instantiate a IR receiver object decode_results results;//instantiate a decode_results object. //This object is separate from the IR receiver. Servo myservo;//instantiate a servo object to control the wing LiquidCrystal_I2C lcd(0x27,16,2);//instantiate a 16x2 I2C LCD display with address 0x27
void setup() { Serial.begin(9600);//Start the serial monitor lcd.init();// initialize the lcd irrecv.enableIRIn(); // Start the receiver myservo.attach(9, 544, 1200);// attaches the servo on pin 9 to the servo object pinMode(6, OUTPUT);//define pin 6 as an output for the motor pinMode(7, OUTPUT);//define pin 7 as an output for the relay pinMode(8, OUTPUT);//define pin 8 as an output for the green LED pinMode(12, OUTPUT);//define pin 12 as an output for the red LED }
void loop() { //get commands from the recvIR function to turn power on with remote control recvIR(); //check the speed of the motors and activate the servo if above threshold activateDRS(); //get the revolutions per milli-second from revPerMilli function revPerMilli(); }
Het idee van de activateDRS functie is om te schakelen van een servo naar een bepaalde positie, wanneer een voorwaarde is voldaan. De voorwaarde is in dit geval de motorSpeed. Als de motorsnelheid groter dan gelijk aan 200 die de servo verplaatsen naar de 60 deg positie is zullen. Als de servo minder dat is 200 dat de servo naar de oorspronkelijke positie terugkeren zal.
int activateDRS(){<br> int pos = 0;//define the pos variable for the position //of the servo int motorSpeed;//define another variable and set it equal to the function //motorController() motorSpeed = motorController(); //move the servo to its active location when the speed of the motors reaches 200 if(motorSpeed >= 200){ for(pos = 60; pos>=0; pos-=1) // goes from 0 degrees to 60 degrees { // in steps of 1 degree myservo.write(pos);// tell servo to go to position in variable 'pos' digitalWrite(8, HIGH); digitalWrite(12, LOW); delay(15);// waits 15ms for the servo to reach the position lcd.setCursor(0,1); lcd.print("DRS: ON "); break;// allow the program to exit after the servo position is reached } //tell the user that the DRS system is ON Serial.println("DRS: ON"); } if(motorSpeed < 200){ for(pos = 0; pos <= 60; pos += 1)// goes from 900 degrees to 0 degrees { myservo.write(pos);// tell servo to go to position in variable 'pos' digitalWrite(8, LOW); digitalWrite(12, HIGH); delay(15);// waits 15ms for the servo to reach the position lcd.setCursor(0,1); lcd.print("DRS: OFF"); break;// allow the program to exit after the servo position is reached } } return motorSpeed; }
De motorcontroller functie gewoon definieert een potentiometer (potmeter) als een analoge ingang en de motor waarde toegewezen aan de digitale bereik dat wordt gebruikt in de activateDRS-functie
int motorController(){<br> //define variables int potPin = A0; int motorPin = 6; int potValue = 0; int motorValue = 0; //define the potPin as an analog input potValue = analogRead(potPin); //map the analog value of the pot pin to the motor motorValue = map(potValue, 0, 1023, 0, 255); //write the analog value of the motor to the PWM motor pin 6 analogWrite(motorPin, motorValue); Serial.println(motorValue); return motorValue; }
We controleren hier om te zien als een bepaalde opdracht is ontvangen. Als er schakelt we het Relais. Als een andere opdracht wordt verzonden, dat het Relais zal blijken uit die snijdt macht aan de motor en servo.
void recvIR(){<br> //has a transmission been received? if (irrecv.decode(&results)) { //Serial.println(results.value);//If yes: interpret the received commands... if (results.value == 12419199){//Power buttom on AOC remote lcd.clear(); lcd.noBacklight();//turn on the backlight delay(100); } if (results.value == 12398799){//Vol up buttom on AOC remote delay(100); lcd.clear(); lcd.backlight();//turn on the backlight lcd.print("System Ready"); digitalWrite(7, HIGH); // turn the Relay on (HIGH is the voltage level) delay(100); } if (results.value == 12392679){//Channel UP buttom on AOC remote lcd.clear(); lcd.print("System OFF"); delay(500); lcd.noBacklight();//turn off the backlight digitalWrite(7, LOW); // turn the Relay off by making the voltage LOW digitalWrite(12, LOW); delay(100); } irrecv.resume(); // Receive the next value } }
De functie revsPerMilli berekent het aantal omwentelingen van het wiel per milliseconde door eerste te wachten om de waarde van de interrupt te verhogen tot boven de 100. Zodra de revoluties 100 bereikt worden de omtrek en de snelheid van het wiel berekend. deze functie maakt gebruik van een ingebouwde Arduino functie genaamd millis om de tijd in milliseconden.
Opmerking: Ik heb niet kunnen krijgen van de encoders om goed te werken zodat deze functie is niet nodig de code werkt. Ik voegde het vooral als een verbetering voor later.
float revPerMilli(){<br> //define variables unsigned int rpmilli; float speed; unsigned long timeold; //calculate the revolutions per milli(second) rpmilli = revolutions/(millis()-timeold); if (revolutions >= 100) { //Update RPM every 100 counts, increase this for better RPM resolution, //decrease for faster update delay(100); //store the previous time in a variable timeold = millis(); revolutions = 0; //calculate the circumference of the wheel float WHEELCIRC = 2 * PI * 0.065; //define the speed of the wheel speed = rpmilli * WHEELCIRC * 3600; Serial.print("RPM: "); Serial.print(rpmilli); delay(100); } return rpmilli; }