Programmering for begyndere Brug af Arduino Fra programmering til mikroprocessor EDR Hillerød Knud Krogsgaard Jensen / OZ1QK 1
Start på Arduino og programmering Programmerings kursus Sidste gang (Introduktion) Programmeringssproget C Programstruktur (Det gentages og udbygges) Indholdet i en mikroprocessor Præsentation af Arduino En mulig brug i Power Meter 2
Fra programmering til mikroprocessor Sidst kikkede vi på: De grundlæggende variable Valg og løkker Test af programmer (Seriel overvågning) Oversættelse af C-kode (kompilering preprocessor - linker) Vi fik talt om installation af Arduino Vi fik talt om at lave et par programmer 3
Fra programmering til mikroprocessor Fra sidst: Jeg glemte en overhead med spørgsmålene: Hvordan var aften? Er der noget jeg skal lave anderledes i fremtiden? Jeg har også tænkt over, at der var nogle som var meget tavse. Hvorfor sagde I ikke så meget? Hvordan undgår vi det? 4
Fra programmering til mikroprocessor Siden sidst: Er der noget fra sidste gang som vi skal uddybe lidt eller gentage på en anden måde? Har der været problemer med Arduino hjemme? Har du fået gang i Arduino? Er der noget vi skal gøre noget ved nu? 5
Kursusaften2 Fra programmering til Mikroprocessor Denne gang skal vi Mere teori om C Strenge og array Funktioner Funktioner med tid Digital ind og udgange Interrupts Gode programmerings vaner / dokumentation Fra program til hardware eller omvendt Lave programmer med funktioner og interrupts 6
Fra programmering til mikroprocessor Efter at have lyttet til diskussionen sidst vil jeg: Tage udgangspunkt i relevante problemløsninger Udgangspunktet er det vi vil med Arduino og C Udgangspunktet er et eller andet man har lyst til at bruge dette værktøj til Det betyder, at når jeg gennemgår et eller andet C - problem eller Arduino problem så er det i høj grad for at løse en eller anden opgave. 7
Fra programmering til mikroprocessor Lige en ting omkring opsætning af Arduino: 8
Fra programmering til mikroprocessor Karakterer og strenge 9
Strenge Strenge bruges til at skrive tekst på display Oversigt: char unsigned char byt word strenge (to typer) 10
Karakterer og strenge char Indeholder et tegn og fylder 1 byt. Tegnene er gemt som ASCII værdier dvs. som tal. Det fører til den lidt specielle at A + 1 = 66 fordi ASCII værdien for A er 65. Det betyder også de er frit valg mellem at skrive: char mychar = 'A'; char mychar = 65; 11
Karakterer og strenge Der er også følgende datatyper med tegn: unsigned char (anbefales ikke, svare til byte) byte word Jeg kan ikke lige se meningen med dem. Kik selv på http://www.arduino.cc/en/reference/homepage 12
Karakterer og strenge Strenge af typen char med null-terminering Eksempler: char Str1[15]; char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'}; char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'}; char Str4[ ] = "arduino"; char Str5[8] = "arduino"; char Str6[15] = "arduino"; Strenge af typen String - object Den venter vi lidt med fordi vi skal buge pointere 13
Fra programmering til mikroprocessor Funktioner 14
C - Funktioner Jeg har lovet at tage udgangspunkt i et problem En funktion bruges når vi skal bruge en bestemt type kode flere steder i programmet vi skal gøre programmet mere overskueligt 15
C - Funktioner En funktion er kode, som vi kan bruge igen og igen. Koden giver man så et navn. Det kan være: En beregning som vi ofte udfører Hente data fra en indgang Skrive til en udgang eller... Vi kan naturligvis skrive koden igen og igen; men Det fylder mere Det er vanskeligt at vedligeholde 16
C - Funktioner Vi har allerede brugt funktioner lcd.setcursor(1,0) delay() Serial.begin(9600) Det er ikke noget nyt og vanskeligt. Nu skal vi lave dem selv og kende de regler der gælder. 17
C - Funktioner Den generelle form for en funktion er: returtype navn (parameterliste) {.. // her sker et eller andet return værdi; }. Funktionerne på sidste sidde gjorde noget uden at give et resultat tilbage. Eller en virkelig funktion:. float temperatur (int sted) { float volt, temp; volt = analogread (sted); temp =...;.//Beregn temperatur ud fra volt return temp; } Skal der ikke noget tilbage undlader man blot return. 18
Variable i funktioner Vi bruger nu funktionen fra før:. float temperatur (int sted) { float volt, temp; volt = analogread (sted); temp =...;..;//Beregn temperatur return(temp); }... main() { float temp;... temp = temperatur( 22);.. } Bemærk at funktionen er defineret inden den bruges! Vi skal se lidt på de forskellige variable. 19
Variable i funktioner Vi bruger nu funktionen fra før:. float temperatur (int sted) { float volt, temp; volt = analogread (sted); temp =...;.//Beregn temperatur return temp; }... main() { float temp;... temp = temperatur( 22);.. } 20
Variable i funktioner Vi bruger nu funktionen fra før:. float temperatur (int sted) { float volt, temp; volt = analogread (sted); temp =...;.//Beregn temperatur return temp; }... main() { float temp;... temp = temperatur( 22);.. } Variablerne: sted, temp og volt gælder kun inde i funktionen Variablerne inde i funktionen forsvinder når funktionen forlades! Der er teknikker til at få variabel til at overleve. Den temp er en anden variabel end den inde i funktionen. (At sætte et tal ind her er dårlig programmering! Vedligehold vanskelig!) 21
Fra programmering til mikroprocessor Delay rutiner med tid 22
Rutiner med tid millis() - returnerer milisekunder siden programstart, Unsigend long. Overflow efter 50 dage. micros() returnerer mikrosekunder siden program start (opløsning 4 usek) unsigned long. Overflow efter 70 min. delay(ms) returnere ingen ting. Venter i antal msek. Variabel er unsigned long ( dvs. 0 4294.967.295 msek) delaymicroseconds(us) returnere ingen ting. Selvom variablen er unsigned int (0 65535) er længste pause 16383 usek.
Fra programmering til mikroprocessor Digital ind / ud 24
Digital ind / ud Det er funktionerne pinmode() - fortæller om et ben er ud eller indgang digitalwrite() - Skriver til en udgang digitalread() - Læser en indgang
Digital ind / ud pinmode() Beskrivelse: Syntax: Parameters Returværdi Sætter et ben som udgang eller indgang PinMode(pin, mode) pin: bennummer for den udgang som mode skal sættes på. mode: INPUT, OUTPUT,eller INPUT_PULLUP. ingen ting (see the digital pins page for a more complete description of the functionality.) Her skal tilføjes noget.
Digital ind / ud digitalwrite() Beskrivelse: Syntax: Parameters: Returnerer: Sætter en ben HIGH eller LOW digitalwrite(pin, value) pin: ben nummer (2 13, se senere) value: HIGH or LOW ingen ting Bemærk ben 13 er lidt speciel. Kræver en ekstern pull down modstand hvis den skal bruges som digital udgang.
Digital ind / ud digitalread() Beskrivelse: Syntax: Parameter Returværdi Læser værdi fra det specificerede ben, enten HIGH eller LOW. digitalread(pin) Pin: Nummeret på det ben som ønskes aflæst HIGH eller LOW
Fra programmering til mikroprocessor Interrupts
Interrupts Interrupts Betyder blot at man afbryder det man er i gang med. Interrupts udnyttes Når man holder øje med noget som indtræffer sjældent - man er fri for at holde øjet hele tiden. Når noget indtræffer som kræver øjeblikkelig handling. F.eks. et signal / en tilstand der kun er der kortvarigt Man kan vælge at se bort fra interrupts i kritiske dele af programmet.
Interrupts Spørgsmålet er nu: Hvordan udnytter vi interrupts?
Fra programmering til mikroprocessor Dokumentation
Gode vaner - Dokumentation, Advarsel: Jeg elsker at dokumentere! Der er nu nogle gode regler som hjælper jer: Bruge versionsnummer / dato i starten Skriv helst hvad filnavnet er. På papir kan man jo ikke se det. Lav et fast hoved hvor I skriver hvem der har lavet programmet og hvad det skal gøre Skriv i programmet hvad det laver Lav indrykninger i programmet. (Det hjælper editoren til med) Ideelt fylder en funktion kun en A4! 33
Gode vaner - Dokumentation // *************************************************************** // SDR-radio VFO // OZ6YM, Palle A. Andersen ( August 2009 ), // revideret til PIC18F4553 den 25.12.2009 // *************************************************************** // PORT-forbrug: PIC16F4553 - konfigurationen: // port RB0 = Rotator A // port RB1 = Rotator B // // =================================================== // 3 porte bruges til styring af DDS: // DDS CPU // ---------------------------------- // DATA (pin3) = RC7 // CLOCK (pin2) = RB5 // LOAD (pin1) = RA3 // Se i øvrigt DDS.h vedr. kalibrering af frekvens-nøjagtighed. // =================================================== // LCD Display driver - STANDARD 4 line x 20 Char display // Forbindelse mellem CPU = PIC18F4553 og LDC, // defineret herunder, er: // 34
Dokumentation - Funktionsbeskrivelse /***************************************************** * Function: void UserInit(void) * PreCondition: None * Input: None * Output: None * Side Effects: None * Overview: This routine should take care of all of the demo code * initialization that is required. * Note: ********************************************************/ void UserInit(void) { unsigned char i; // InitializeUSART(); 35
Fra program til hardware, Måske er det kun mig der har problemet: Hvor er bestemmer jeg hvilke udgange jeg bruge til hvad? Der er jo ikke helt frit valg Der er digitale ben Der er analoge ben Vi kikker lidt mere på dem 36
Fra program til hardware De digitale ind- udgange (Analoge udgange): Pin / ben Dig. ind/ud Anal. udg. 0 RX 1 TX 2 Ext intr 0 3 Ext intr 1 PWM 4 5 PWM 6 PWM 7 PWM = Pulse Width Modulation Pin / ben Dig. ind/ud Anal. udg. 8 9 PWM 10 PWM 11 PWM 12 13 37
Fra program til hardware De analoge indgange: Analog pin A0 A1 A2 A3 A4 A5 38
Fra program til hardware Hvordan ses det i programmet? Vi kikker på et par programmer som vi måske kender. 39
Fra program til hardware Programmet Blink const int ledpin = 13; /* LED connected to digital pin 13*/ /* The setup() method runs once, when the sketch starts*/ void setup() { pinmode(ledpin, OUTPUT); /* initialize the digital pin as an output*/ } // the loop() method runs over and over again */ void loop() { digitalwrite(ledpin, HIGH); // turn the LED on delay(1000); // wait a second digitalwrite(ledpin, LOW); // turn the LED off delay(1000); // wait a second } 40
Fra program til hardware Programmet Blink const int ledpin = 13; /* LED connected to digital pin 13*/ /* The setup() method runs once, when the sketch starts*/ void setup() { pinmode(ledpin, OUTPUT); /* initialize the digital pin as an output*/ } // the loop() method runs over and over again */ void loop() { digitalwrite(ledpin, HIGH); // turn the LED on delay(1000); // wait a second digitalwrite(ledpin, LOW); // turn the LED off delay(1000); // wait a second } Her udpeges ben 13. Der er ikke andet specielt end her sidder en lysdiode. 41
Fra program til hardware /*LiquidCrystal Library - Hello World Demonstrates the use of a 16 2 LCD display. */ #include <LiquidCrystal.h> /*constants for the number of rows and columns in the LCD */ const int numrows = 2; const int numcols = 16; /* initialize the library with the numbers of the interface pins*/ LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { lcd.begin(numcols, numrows); lcd.print("hello, world!"); /* Print a message to the LCD.*/ } void loop() { /* set the cursor to column 0, line 1 (note: line 1 is the second row, since counting begins with 0):*/ lcd.setcursor(0, 1); /* print the number of seconds since reset:*/ lcd.print(millis()/1000); } Uden at gå i detaljer så vælges adresselinjerne til display til ben 5, 4, 3 og 2. Det undre mig se næste 42
Fra program til hardware De digitale ind- udgange analoge udgange: Pin / ben 0 RX 1 TX 2 Ext intr 0 Digi. udg. 3 Ext intr 1 PWM 4 5 PWM 6 PWM 7 Pin / ben Digi. udg. 8 9 PWM 10 PWM 11 PWM 12 13 43
Fra program til hardware Hvis nu man gør således i stedet #include <LiquidCrystal.h> /*constants for the number of rows and columns in the LCD */ const int numrows = 2; const int numcols = 16; /* initialize the library with the numbers of the interface pins*/ LiquidCrystal lcd(12, 11, 6, 5, 4, 3); void setup() { lcd.begin(numcols, numrows); lcd.print("hello, world!"); /* Print a message to the LCD.*/ } void loop() { /* set the cursor to column 0, line 1 (note: line 1 is the second row, since counting begins with 0):*/ lcd.setcursor(0, 1); /* print the number of seconds since reset:*/ lcd.print(millis()/1000); } Nu bruges ben 6, 5, 4 og 3 til adresse for display. Det er prøvet og virker! Ben 2 kan nu bruges til interrupt. 44
Fra program til hardware Programmerings kursus Kursusaften 1 Start på programmering efter en Pause 45
Fra program til hardware Til slut: Hvordan har det været i aften? Er der noget jeg skal lave anderledes i fremtiden? Hvis der noget I tumler med som I gerne vil have belyst så ring eller skriv en mail. Jeg vil forsøge at tage det op den følgende gang.
, Fra programmering til Mikroprocessor Tak for i aften På gensyn den mandag den 22. oktober Jeg er her dog næste tirsdag. I er velkommende til at ringe eller sende en mail. 47