kompendium. Dette kompendium er ikke et forsøg på at være fyldestgørende, for at komme i gang med at programmere, men er en samling af informationer og tips. Og der er en række links til materialer på nettet, - derude er der en sand guldgrubbe af materiale. Søg blot på + det, du leder efter. Mangler der noget, giv mig et hint. / Valle s oprindelse: En er et lille kit, der programmeres via USBstikket direkte fra udviklingspro grammet. The picturesque town of Ivrea, which straddles the blue-green Dora Baltea River in northern Italy, is famous for its underdog kings. In 1002, King Arduin became the ruler of the country, only to be dethroned by King Henry II, of Germany, two years later. Today, the Bar di Re, a pub on a cobblestoned street in town, honors his memory, and that s where an unlikely new king was born. The bar is the watering hole of Massimo Banzi, the Italian cofounder of the electronics project that he named in honor of the place. Processoren på kittet er fra Atmel, af AVR-familien, og hedder Atmega 328. Datablad for processoren: se http://www.atmel.com/images/doc8161.pdf Udviklingssproget til er en af-art af programmeringssproget C++. (C++ med twist ). Side 1 af 35
Timeline: AVR-familien er udviklet i 1996 af ATMEL. Arkitekturen er lavet af Alf-Egil Bogen og Vegard Wollan, og har fået sit navn af: Alf-Egil Bogen Vegard Wollan RISC microcontroller, også kendt som Advanced Virtual RISC. Controlleren AT90S8515 var den første microcontroller der var baseret på AVR arkitekturen. 1 På linket http://learn.adafruit.com/arduino-tips-tricks-and-techniques/arduino-uno-faq ses en lille video, der beskriver udviklingen af forskellige generationer af. Eller se en dokumentar-film om Uno er en af de seneste versioner, - og er nu ude i revision 3, ( ses på bagsiden af kittet, mærket Uno R3 ) Senere kit: Leonardo fra 2012, Måder at bruge på: Når kittet er programmeret, kan det køre uden PC-tilslutning, blot det får en extern powersupply. Eller det kan køre med computeren tilsluttet, hvorved man tillige har mulighed for at sende data frem og tilbage On the fly mellem kittet og PC-en. Og endelig kan man tage kittets programmerede uc ud, - og sætte den på sit eget print eller fumlebrædt. Her kan man evt. montere et stik, der muliggør direkte in circuit programmering med specielle USB-stik. Processorens pins er ført ud til nogle hunstik, hvorfra signaler kan videreføres med nogle ledninger til et fumlebrædt. Hvis USB er tilsluttet, kan kittet køre direkte fra PC ens power. Hvis den skal køre uden USB, forsynes den fra en netadapter, 7 12 Volt, med plus i midten: 1 http://www.engineersgarage.com/articles/avr-microcontroller Side 2 af 35
Tekniske specifikationer: 2 Microcontroller ATmega328 Operating Voltage 5V Input Voltage (recommended) 7-12V Digital I/O Pins 14 (of which 6 provide PWM output) Analog Input Pins 6 DC Current per I/O Pin 40 ma Flash Memory 32 KB (ATmega328) of which 0.5 KB used by bootloader SRAM 2 KB (ATmega328) EEPROM 1 KB (ATmega328) Clock Speed 16 MHz Se endvidere datablad for processoren, fra Farnell: http://www.farnell.com/datasheets/810076.pdf Board-diagram: http://arduino.cc/en/uploads/main/arduino-uno-schematic.pdf Pins: Pins numre 0 til 13 er enten Input eller Output. De 6 pins, der har en lille bølgelinje, ~ foran nummeret, kan bruges som analogt output. Det er dog ikke en analog DC, men et PWMoutput, der kan bruges til at dæmpe fx lysdioder. Processoren kører på 16 MHz. Et Fumlebrædt kan forsynes fra en fra pin mærket 5 V, og der er 2 Gnd-pins. På pin 13 er der en LED direkte på boardet, der viser om pin 13 er høj. De pins, der skal bruges i programmet, kan defineres med et navn og som int, dvs. integer. ( Heltal ) Dvs. at pinnumrene får tildelt et navn. Det er smart, idet man så let senere kan ændre pinnummer for alle referencer til pågældende pin længere nede i programmet, blot ved at ændre i programmets opsætningsdel i toppen! Pins mærket A0 til A5 er analoge pins. De betyder, at processoren kan måle og omsætte et analogt inputsignal til et digitalt tal. De kan også bruges som Input/Output. Pin 0 og 1 er ført til processorens UART. De kan desværre ikke bruges, hvis arduinoen er tilsluttet PC-en via USB, idet kommunikationen mellem de to foregår via UART en. 2 http://arduino.cc/en/main/arduinoboarduno Side 3 af 35
Kilde: http://arduino-info.wikispaces.com/pincurrent Hver pin kan levere +/- 40 ma. ( Kilde# 3 ) DC Current VCC og GND pins: 200 ma Der sidder en sikring på boardet der begrænser overbelastning af pin-ene Der må sættes 8 10 V på pin Vin, der går til 7805-indgangen. Der er ligeledes en 3V3 pin med meget præcis regulator. Den kan evt. bruges i opstillinger som reference-spænding http://playground.arduino.cc/main/pincurrentlimitations Her er vist en oversigt over sammenhængen mellem uc ens porte og I/O pinnumre i -verdenen. Søg på Pin Mapping For Mega, se link: 4 http://forum.arduino.cc/index.php/topic,45329.0.html 3 http://docs-asia.electrocomponents.com/webdocs/0e8b/0900766b80e8ba21.pdf 4 http://forum.arduino.cc/index.php/topic,45329.0.html Side 4 af 35
Udviklingsprogrammet: Start udviklingsprogrammet, der også kaldes for IDE. IDE ( Integrated Development Environment ) Et kilde-program i verdenen kaldes en sketch. En sketch gemmes med extension.ino. Default gemmes sketches i folderen: / dokument /. De vil så automatisk ses i Sketchbook menuen! Bemærk, at der automatisk oprettes en mappe, hvori programmet gemmes, med samme navn som kildetekst-filen. Obs: Brug aldrig de danske Specialbogstaver til filnavne, heller ikke i fil-stien. IDE, Udviklingssoftware / Knapper Verificer. Dvs. Compiler ( oversæt ) programmet, og tjek for sproglige og syntax-fejl. Compiler og Upload til -hardwaren. I bunden kan ses, hvor stor fil, der uploades. Husk først at vælge det rigtige board, og rigtige Com-port. Vælg Tools / Board, og Tools / Serial Port. Når der er uploaded, vil det nye program starte med at køre! Ny kildetekstfil. ( sketch ) Åbn en gemt fil. Gem fil Side 5 af 35
Indstilling af Boardtype og COM-Port. For at man kan Compilere til det rigtige board, skal boardtypen vælges, - og der skal vælges den rigtige COM-port, som boardet har fået tildelt ved tilslutningen til USBporten. Se evt. om Enhedshåndtering i kompendiet. ( Om installation af drivere ) Opbygning af kildetekst: Find evt. det eksempel på en blinkende LED, der følger med: Side 6 af 35
En Kildetekst opdeles altid i 4 eller flere dele. Øverst ses først en Header, dvs. en kommentar-del, hvor man med ren tekst forklarer hvad programmet skal gøre. Hvem der er programmør, dato osv. Kommentar indsættes mellem /* og */. Bruger man kun 1 linje kommentar, kan man i stedet bruge //. Dernæst kommer en erklæringsdel. Her defineres variabel-navne, navne på pins, navne på konstanter, osv. Variable er navne på RAM, der kan indeholde et tal. For at Compileren kan vide hvor mange Byte, der skal afsættes til en variabel, skan man angive det. Fx med int, der står for integer, der betyder et heltal, 16 bit.. #define constantname value #define ledpin 3 const float pi = 3.14; ROM en const byte buttonpin = 12; // #define er dog ikke vellidt, idet konstanten // placeres i RAM, og derved optager plads. // Const tvinger compileren til at placer pi i //pinnavn til trykknap const int shorttime = 5; const long longtime = 3*shortTime; char message[] = "I support Valle."; volatile int state = LOW; volatile byte seconds; // Hvis programmet bruger interrupts, skal de // variable, der bruges både i hovedprogrammet // og i interrupt-service-rutinen erklæres som // volatile. void setup( ). Side 7 af 35
I næste afdeling placeres et program, der hedder void setup( ). Det er en programdel, der kun udføres 1 gang ved power-on, eller ved reset. I denne del defineres kontrollerens ben til at være udgange eller indgange, og hvad de skal starte med at være, høje eller lave. void setup() pinmode(buttonpin, INPUT); // initializer pin som input: digitalwrite(buttonpin, HIGH); // gør pin høj. Serial.begin(9600); // initialiser serial communikation: Definer altid Output efter pinmode. void loop( ) I den 4. del placeres den programdel, der kører i loop. Alle arduino-programmer skal minimum have en setup-del og en loop-løkke. En Loop-løkke, fordi en processor ikke kan lave ingenting! Funktioner() Delprogrammer, - underprogrammer eller funktioner kan med fordel placeres i selvstændige afsnit. Evt. kan de placeres i nye tabs. Se senere Funktioner kan placeres efter void Loop(), mellem void setup() og void Loop(), eller de kan placeres i selvstændige tabs. An program is structured in four parts. FIRST: Begin with some comments about the program SECOND: List variables and constants that all the functions may use. Variables are names for memory locations that a computer can use to store information that might change. Constants are numbers that won t change. THIRD: Run the setup() function to prepare stuff. This is where you perform tasks that you want done once at the beginning of your program void setup() Side 8 af 35
// do things once at the start of the program FOURTH: Run the loop() function. This is where you run things in a sequence from the top of the loop to the bottom of the loop, then you start over again at the top, looping until the machine gets turned off void loop() // Do the first thing // Do the second thing // Do any number of things // Do the last thing in the list // Go back to the beginning of this list Se Cookbook: http://www.insidescan.com/roboag//.cookbook.pdf Se evt følgende: Kilde: Google: lecture_programming_microcontrollers.ppt eller: http://www.search-document.com/ppt/1/1/mico-controller-programming.html Funktionsnavne i IDE, Kamelskrift Forklaring på navne i -IDE camelcase er en måde at sammensætte ord uden bindestreg eller mellemrum, men med første bogstav i 2. og efterfølgende ord skrevet med stort. Side 9 af 35
Navnet kommer sandsynligvis fra at versalerne midt i ordet ser ud som pukler på en kamel. camelcasemedlillebegyndelsesbogstav camelcase forveksles ofte med PascalCase, hvor også det første bogstav skrives med stort Hjælp: Find let hjælp på IDE, -> Help -> Reference Links til online materiale: På nettet findes et hav af materiale om. Specielt anbefales at se på en videoserie lavet af en ung gut, Jeremy Blum: Se http://www.jeremyblum.com/portfolio/arduino-tutorial-series/ Play-List: http://www.youtube.com/playlist?list=pla567ce235d39fa84 Getting started: For beginners: http://startingelectronics.com/beginners/ Der findes et hav af info om specifikke opgaver på s egen hjemmeside: http://arduino.cc/en/tutorial/homepage http://tronixstuff.wordpress.com/tutorials/ http://www.ele.uri.edu/courses/ele205/%20-%20learning.pdf Pdf med interne links! Ret god!! http://www.ele.uri.edu/courses/ele205/ele205lab/ele205_lab_files/%20-%20learning.pdf http://www.ladyada.net/learn/arduino/index.html Link til Include-biblioteker: http://arduino.cc/en/reference/libraries Håndtering af værdier og Tal Tal gemmes i variable, der jo selvfølgelig gemmes i processorens RAM. Tallene tildeles et navn i programmet, men compileren vælger selv, hvor i RAM-en de gemmes. Side 10 af 35
Variabel: Bytes Range, Kan antage værdierne: int 2-32768 til 32767 Repræsenterer positive og negative heltal This is most commonly what you see used for general purpose variables in example code provided with the IDE. unsigned int 2 0 til 65535 Repræsenterer kun positive tal long 4 Unsigned long 4 float 4 3.4028235E+38 til -3.4028235E+38. They are stored as 32 bits (4 bytes) of information. double 4 På nogle nye boards er de 8 byte! boolean 1 False (0) eller true (1) Også LOW og HIGH, 0 og 1. char 1-128 til 127 Repræsenterer 1 enkel karakter eller en signed værdi mellem -128 og 127 The compiler will attempt to interpret this data type as a character in some circumstances, which may yield unexpected results. byte 1 0 til 255 Som char, men for unsigned værdier byte b = B10010; Word = Unsigned int. string 0 to 65535 word w = 10000; I -verdenen er det let at lave beregninger på variable. For en oversigt over de mulige matematiske operatorer, se: http://www.arduino.cc/en/reference/homepage Matematiske operationer: Operator Eksempel Ækvivalent udtryk Kommentar += Value += 5; Value = Value + 5; // add 5 to Value -= Value -= 4; Value = Value - 4; // subtract 4 from Value *= Value *= 3; Value = Value * 3; // multiply Value by 3 /= Value /= 2; Value = Value / 2; // divide Value by 2 >>= Value >>= 2; Value = Value >> 2; // shift Value right two places Side 11 af 35
<<= Value <<= 2; Value = Value << 2; // shift Value left two places &= Mask &= 2; Mask = Mask & 2; // binary and Mask with 2 = Mask = 2; Mask = Mask 2; // binary or Mask with 2 Boolske operationer: Symbol Funktion Kommentar Eksempel & Bitwise And Sets bits in each place to 1 if both bits are 1; otherwise, bits are set to 0. 3 & 1 equals 1 (11 & 01 equals 01) Bitwise Or Sets bits in each place to 1 if either bit is 1. 3 1 equals 3 (11 01 equals 11) ^ Bitwise Exclusive Or Sets bits in each place to 1 only if one of the two bits is 1. 3 ^ 1 equals 2 (11 ^ 01 equals 10) ~ Bitwise Negation Inverts the value of each bit. The result depends on the number of bits in the data type. ~1 equals 254 (~00000001 equals 11111110) Eksempler på Logiske operatorer Konvertering mellem talformater: Floatvaerdi = float( int eller byte værdi * fx4.0); Konvertering til float: Side 12 af 35
Værdi@float = float(tal); // kan være byte eller int. Arrays int myarray[] = 1, 2, 3, 4, 5, 6; Note that arrays start counting from 0. This means that the first position in an array is 0. In the example above the number 1 is store in the first position in the array and if we were to call for this value we would have to do it as: mynumber = myarray[0]; Se fx: http://forum.arduino.cc/index.php/topic,46931.0.html Paranteser: I IDE en bruges paranteser til at strukturere programmet. Overordnede strukturer omkranses af, og underordnede kommandoer af ( ). Ved debuging kan man placere cursoren til højre for fx så highlightes den tilhørende klamme. Det gør det let at se, hvordan strukturen hænger sammen Dobbeltklikkes på stedet, farves en hel blok. Vælges Værktøjer -> Autoformatering struktureres programmet automatisk med tabulator-indrykning Programeksempler: ( Bygget mere eller mindre over JeremyBlum s Youtube videos! De er bare geniale!!) Se: http://www.youtube.com/course?list=eca567ce235d39fa84 Se evt. side med de første 10 ting, man gør når man begynder at lære programmering: http://antipastohw.blogspot.dk/2009/12/first-10-things-everyone-does-with.html Side 13 af 35
int switchpin = 8; int ledpin = 13; boolean lastbutton = LOW; boolean ledon = false; // Boolean kan sættes til LOW, False eller 0, // eller high, osv. Void setup() // Opsætning, køres 1 gang! pinmode(switchpin, INPUT); // Definer og sæt pin 8 op som input pinmode(ledpin, OUTPUT); // Do, pin 13 som output Void loop() // Herefter følger loop -rutinen. If ( digitalread(switchpin) == HIGH) digitalwrite(ledpin, HIGH); else digitalwrite(ledpin, LOW); && betyder AND! int switchpin = 8; int ledpin = 13; boolean lastbutton = LOW; boolean ledon = false; void setup() pinmode(switchpin, INPUT); pinmode(ledpin, OUTPUT); void loop() if (digitalread(switchpin) == HIGH && lastbutton == LOW) // If button went from Low to High Side 14 af 35
ledon =!ledon; // LED changes state lastbutton = HIGH; else //lastbutton = LOW; lastbutton = digitalread(switchpin); // update lastbutton state digitalwrite(ledpin, ledon); // update LED state --- Subrutine: void setup() lalalalal void loop() do something; subroutinename(); //end //calls your subroutine void subroutinename() whatever you want it to do Boolean debounce(boolean last) Boolean current = digitalread(switchpin); If (last!= current) Delay(5); current = digitalread(switchpin); Return current; En subroutine kaldes sådan: Side 15 af 35
currentbutton = debounce(lastbutton); Analog output: Pwm output mærket ~ er pseudo analog outputpin, - der godt kan bruges til at dæmpe LED-lys: Men det er en PWM-output, der pulses!! Der kan sendes værdier fra 0 til 255 til en Pin. Eksempel på, at læse et potmeter, og sende Seriel til PC-en i debug-vinduet: int ledpin = 13; Void setup() pinmode(buttonpin, INPUT); // sætter button pin som input Serial.begin(9600); // tillad seriel kom! void loop() Serial.println(digitalRead(buttonPin)); Delay(1000); // vent 1 sekund, så print igen! Eksempel på analogread; Serial.Println(analogRead(potPin)); Delay(1000); // print pin-værdien Læser fra 0 til 1023, fx hvis der sættes et potentiometer på en analog input pin og der justeres fra 0 til 5 Volt. Dvs. 10 bit opløsning! Eksempel: læs spænding på pin, og skriv på PC. int sensepin = 0; void setup() analogreference(default); // er ikke nødvendig Side 16 af 35
Serial.begin(9600); Void loop() Serial.println(analogRead(sensePin)); Delay(500); Lyscensor: int sensepin = 0; int ledpin = 9; Void setup() analogreference(default); // Er ikke nødvendig! pinmode(ledpin, OUTPUT); void loop() int val = analogread(sensepin); if(val < 800) digitalwrite(ledpin, HIGH); else digitalwrite(ledpin, LOW); Eksempel: void loop() int val = analogread(sensepin); // Læs værdi fra 0 til 1023 val = constrain(val, 750, 900); Int ledlevel = map(val, 750, 900, 255, 0); analogwrite(ledpin, ledlevel); // Funktionen constrain afrunder værdien val til kun // at ligge i intervallet vist, altså fra 750 til 900 // Funktionen map vil tage værdien val, og lave værdier // fra 750 til 900 om til værdier fra 255 til 0 jævnt fordelt!! Episode #5, Motorer og transistorer. DC-Motor PWM. Side 17 af 35
Følgende eksempel får en motor styret af en switch-transistor til at køre hurtigere og dernæst langsommere. Motor accelereres af tallene fra 0 til 255. PWM.!! Def af Var?? Void Loop() For ( int I = 0; i<=255; i++) analogwrite(motorpin,i) delay(10); delay(500); for ( int i = 255; i>=0; i--) analogwrite(motorpin,i) delay(10); delay(500); Servomotor. I er der et driverbibliotek til Servomotorer. Den er beregnet til at koble direkte til uc-en. Vores kit skal have tilsendt en ID + 4 bytes med info om servoernes position. Første eksempel får bare motoren til at køre frem og tilbage: int servopin = 9; // Def servopin, fx pin 9 #include <Servo.h> Servo MinServo; // brug et bibliotek, med kode til at styre en servo-motor // Typen Servo, kaldet MinServo Void Setup() MinServo.attatch(servopin); Void loop() For (int i =0; i<=180; i=i+20); MinServo.Write(i); Delay(1000); ;--------------------------------------------------------- 2. eksempel, hvor motorens stilling styres af en læsning af den analoge spænding på en pin: Side 18 af 35
void loop() int dist = analogread(distpin); int pos = map(dist, 0, 1023, 0 180); // der læses på pin, værdier fra 0 til 1023. Disse værdier laves om til værdier // mellem 0 og 180, og stoppes ind i variablen pos. //Som do! ;-------------------- /* Servo Test sketch */ #include <Servo.h> Servo servomain; // Define our Servo void setup() servomain.attach(10); // servo on digital pin 10 void loop() servomain.write(45); // Turn Servo Left to 45 degrees delay(1000); // Wait 1 second servomain.write(0); // Turn Servo Left to 0 degrees delay(1000); // Wait 1 second servomain.write(90); // Turn Servo back to center position (90 degrees) delay(1000); // Wait 1 second servomain.write(135); // Turn Servo Right to 135 degrees delay(1000); // Wait 1 second servomain.write(180); // Turn Servo Right to 180 degrees delay(1000); // Wait 1 second servomain.write(90); // Turn Servo back to center position (90 degrees) delay(1000); // Wait 1 second Episode # 6 Seriel kommunikation: Se fx: http://www.ladyada.net/learn/arduino/lesson4.html Hvordan PC-en kan forbindes til via Rx og Tx, Pin 0 og 1. Side 19 af 35
-C-sproget er baseret på et sprog, der hedder Processing. Det er et sprog, der kan bruges til at skabe programmer på PC-skærmen. Processing er et Crossplatform program! Tx og Rx bruges til kommunikationen mellem PC og kit. Derfor kan de ikke bruges samtidig med at den er sluttet til PC-en. For at det kan gøres, skal der bruges en større, fx Mega, eller der skal anvendes softserial. Først leges lidt med seriel input boksen på skærmen: Void Setup() Seriel.begin(9600); // Create seriel object Void loop() While ( seriel.available() = 0); // vent til der kommer en værdi til kittet Int val=seriel.read(); // echo input til PC-en! Seriel.Println(val); // send til PC // dvs. når der indtastes et tal, sendes der et tal retur til PC-en // sendes et 0, returneres der et 48. ( Se ascii tabellen ) et 1 -> 49. // Evt. kan der skrives: int val = Seriel.Read() 0 ); Eks. På at styre noget på kittet: If (val ==1) Seriel.Println( Led er on ); Digital.Write(LedPin, High); Else if(val==0) Seriel.Println( Led er off ); Digital.Write(LedPin, low); Else Seriel.Println( Invalid ); Seriel.flush(); // Tøm buffer!?? Side 20 af 35
En else if blok kan bruges med eller uden en afsluttende else block og modsat. Man kan bruge et ubegrænset antal else if blokke. if (pinfiveinput < 500) // do Thing A else if (pinfiveinput >= 1000) // do Thing B else // do Thing C Herefter kommer noget kode skrevet til Processing-sproget til PC-en. Vinduet ligner det, der skrives i til -udviklingen. I2C Episode #7, Dette eksempel er til kredsen fra Microchip: TC74A0. Forbindelserne er vist fastlagt på forhånd i biblioteket,: SDA ( A04 ) SCL ( A05 ) #include <Wire.h> // Include the Wire Library int temp_address = 72; // set the address på temp sensor void setup() Serial.begin(9600); Wire.begin(); På PC-en ses dette: Void loop() // Send a request Wire.beginTransmission(temp_address); // Start Talking Wire.endTransmission(); // Ask for Register zero Side 21 af 35
Wire.requestFrom(temp_address, 1); // Request 1 byte while(wire.available() == 0); // Wait for response int c = Wire.receive(); // get the temp // Convert fra Cencius tuil Farenheit ( eksempel ) int f = round(c*9.0/5.0 + 32.0); //Send til PC, skriv resultatet Serial.print(c); Serial.print( C ); Serial.print(f); Serial.println( F ); // Ingen ny linje! // Skriv C for Celcius // Nu med ny linje delay(500); Afsnittet fortsætter med noget kode til Processing!! Der laves et vindue med: SPI kommunikation: Episode #8 Eksemplet bruger en digital pot. En AD5204, der bruges til at styre formodstanden foran 3 lysdioder. Side 22 af 35
I biblioteket er der default brugt Pin 11 = serial into slave, MoSi Pin 13 = Clk Pin 12 = Slave out, into master?? SoMi. #Include <SPI.h> int SS = 10; defineret i lib. //Include SPI Library // Sæt Slave Select pin, Pinnr er valgfri!, de andre er void setup() pinmode(ss, Output); // Sæt Pin 10 til output. De andre håndteres automatisk! SPI.begin(); // Initier SPI // her kommer en funktion til at styre pot void setled(int reg, int level) // funktionen har 2 parametre! // Potmeteret styres af 4 registre, 0 til 3 // Level er fra 0 til 255! digitalwrite(ss, LOW); SPI.transfer(reg); SPI.transfer(level); digitalwrite(ss, High); // Chip selectes. // Send Reg nummer // Så kommer loop-en! void loop() for(int i =0; i<=2; i++) for ( int j=50; j<=255; j++) setled(i,j); // Send værdier til funktionen delay(20); Delay(500); // Delay på fuld skrald Side 23 af 35
for ( int j=255; j>= 50; j--) setled(i,j); // Send værdier til funktionen delay(20); Episode # 09, Wireless Communication Eksempel: float value = 1.1 void setup() Serial.begin(9600); void loop() value = value 0.1; // værdien reduceres med 0,1 for hver loop if( value == 0) Serial.println( Værdien er nøjagtig 0 ); Else if(almostequal(value, 0)) // Værdien næsten lig 0 Serial.print( Værdien ); Serial.print(value,7); // print til 7 decimalpladser Serial.println( er næsten lig 0 ); else Serial.println(value); Delay(100); /* Simple Cylon Cylon Eye sweep using 5 LEDs */ unsigned char updown=1; // start off going UP unsigned char cylon=0; // determines which LED is on 0 to 4 Side 24 af 35
void setup() // initialize the digital pins as outputs. DDRB = B00011111; // sets port B pins 0 to 4 as outputs void loop() if(updown==1) cylon++; if(cylon>=4) updown=0; else cylon--; if(cylon==0) updown=1; PORTB = 1 << cylon; delay(150); // Reached max LED, next time we need to go down // Reached min LED, next time we need to go up // wait for a second //---------------- LCD // Se evt. bibliotek: http://arduino.cc/en/reference/liquidcrystal?from=tutorial.lcdlibrary http://www.youtube.com/watch?v=jdotn1slxwq /* LiquidCrystal Library - Hobbytronics Demonstrates the use a 16x2 LCD display. The LiquidCrystal library works with all LC D displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch prints "Hobbytronics" to the LCD and shows the time. This sketch is based on the sample sketch at http://www.arduino.cc/en/tutoria l/liquidcrystal but with modifications to the LCD contrast to make it adjustable via software The circuit: * LCD RS pin to digital pin 12 * LCD Enable pin to digital pin 11 * LCD R/W pin to Ground, only Write to LCD. * LCD VO pin (pin 3) to PWM pin 9 * LCD D4 pin to digital pin 5 * LCD D5 pin to digital pin 4 * LCD D6 pin to digital pin 3 * LCD D7 pin to digital pin 2 */ // include the library code: #include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins LiquidCrystal lcd(12, 11, 5, 4, 3, 2); Side 25 af 35
void setup() pinmode(9, OUTPUT); // declare pin 9 to be an output: analogwrite(9, 50); lcd.begin(20, 4); // set up the LCD's number of columns and rows: lcd.print(" HobbyTronics"); // Print a message to the LCD. void loop() // set the cursor to column 0, line 1 ( line 0 3 ) lcd.setcursor(0, 1); // print the number of seconds since reset: lcd.print(millis()/1000); Se også Jeremy s tutorial episode #13 //Examples of lcd.print() lcd.print("hello World"); lcd.print(variable); lcd.print(variable,dec); //*** Make sure you do not exceed the number of columns of the LCD module. // lcd.setcursor(); Examples of setcursor() lcd.setcursor(0,0); lcd.setcursor(9,1); lcd.clear(); // Jump to the top left corner // Jump to column 10, second row //Clear Screen ;------------------------ Eksempel på Pin-interrupts: http://arduino.cc/en/reference/attachinterrupt // toggles LED when interrupt pin changes state int pin = 13; volatile int state = LOW; void setup() pinmode(pin, OUTPUT); attachinterrupt(0, blink, CHANGE); void loop() Side 26 af 35
digitalwrite(pin, state); void blink() state =!state; Serial kommunikation: Txd & RxD Se: http://www.arduino.cc/en/tutorial/softwareserial void setup() Serial.begin(9600); void loop() int incomingbyte; if(serial.available() > 0) incomingbyte = Serial.read(); Serial.write(incomingByte); // read the incoming byte: // echo I2C Kilde: http://startingelectronics.com/beginners/start-electronics-now/tut18-two-wire-arduino-knight-rider/ /*-------------------------------------------------------------- Program: two_wire_knigh_rider Description: Uses a PCF8574 IO Expander IC on the TWI bus to interface 8 LEDs. A "knight rider" display is shown on the LEDs. Date: 25 April 2012 Author: W.A. Smith, http://startingelectronics.com --------------------------------------------------------------*/ #include <Wire.h> // address of PCF8574 IC on TWI bus Side 27 af 35
#define IO_ADDR (0x40 >> 1) void setup() Wire.begin(); // initialize the I2C/TWI interface void loop() static unsigned char data = 0x01; // data to display on LEDs static unsigned char direc = 1; // direction of knight rider display // send the data to the LEDs Wire.beginTransmission(IO_ADDR); Wire.write(~data); Wire.endTransmission(); delay(70); // speed of display // shift the on LED in the specified direction if (direc) data <<= 1; else data >>= 1; // see if a direction change is needed if (data == 0x80) direc = 0; if (data == 0x01) direc = 1; EEPROM: http://tronixstuff.wordpress.com/2011/03/16/tutorial-your-arduinos-inbuilt-eeprom/ Touch-pad: http://www.instructables.com/id/-laptop-touchpad/ For retning af fejl i Cookbook: Se: http://oreilly.com/catalog/errata.csp?isbn=9780596802486 Se side: http://www.insidescan.com/roboag/ http://tronixstuff.wordpress.com/tutorials/ Direkte portmanipulation: Portmanipulation: http://tronixstuff.wordpress.com/2011/10/22/tutorial-arduino-port-manipulation/ http://www.instructables.com/id/-is-slow-and-how-to-fix-it/ Side 28 af 35
Millis() I IDE-verdenen er der indbygget nogle funktioner, man i sit program kan gøre brug af. Fx millis(). Mens ens program afvikles, har compileren sørget for, at programmet afbrydes af et interrupt hver millisekund fra timer 0, og opdaterer en unsigned long system-variabel med navn millis. Det er den indbyggede Timer 0 der bruges. Millis() function: Der bruges en Unsigned long 32bit variable. Det betyder at den kan tælle fra 0 og op til 2^32-1 millisekunder. ( = 4.294.967.295 ) Dette svarer til: (2^32-1) / 1000ms / 60sec / 60min / 24hr = 49.71 dage, eller 49 dage og 17 timer. Millis() is derived from timer0_millis, unsigned long Target; void setup( void ) Target = millis() + 1000; void loop( void ) if ( millis() >= Target ) /* Do our thing */ Target = millis() + 1000; Det betyder så, at hvis der udmåles en tid ved hjælp af millis, vil der ske fejl efter 49 dage. Da vil variablen millis give overflow og starte forfra igen. Dette er illustreret i denne skitse. Ttotal = tmax t1 + t2 + 1 Millis() t1 t2 Work Around /* kursus oktober 2013 Ur */ Side 29 af 35
// Konstanter const byte ledpin = 13; const unsigned int tdelay = 1000; const unsigned long maxcount = 4294967295; // Variabler byte sekundtaeller = 0; byte minuttaeller = 0; byte timetaeller = 0; unsigned long newtime = 0; unsigned long oldtime = 0; unsigned long difftime = 0; void setup() Serial.begin(9600); pinmode(ledpin, OUTPUT); digitalwrite(ledpin, LOW); void loop() printtid(); sekundtaeller++; if(sekundtaeller > 59) minuttaeller++; sekundtaeller = 0; if(minuttaeller > 59) timetaeller++; minuttaeller = 0; delayultra(); // Den præcise delayfunktion //##### SUBs ##### // Den præcise delayfunktion void delayultra() while (difftime < tdelay) newtime = millis(); if(newtime >= oldtime) difftime = newtime - oldtime; else difftime = maxcount - oldtime + newtime + 1; oldtime = newtime; difftime = 0; void printtid() Side 30 af 35
Serial.print( "Tid: "); if(timetaeller < 10) Serial.print("0"); if(timetaeller < 1) Serial.print("0"); else Serial.print(timeTaeller, 1); Serial.print(":"); if(minuttaeller < 10) Serial.print("0"); if(minuttaeller < 1) Serial.print("0"); else Serial.print(minutTaeller, 1); Serial.print(":"); if(sekundtaeller < 10) Serial.print("0"); if(sekundtaeller < 1) Serial.println("0"); else Serial.println( sekundtaeller, 1); // ##### Ikke flere SUBs ##### Mega Pinout: Side 31 af 35
Andre kredse, der måske kunne være interessante: I2C: PCF8575, 16 bit I/O SPI: MCP23017 ( fås ikke?? ) 74HC4067, 16 kanal analog mux. Oversigt over smarte funktioner i C++ Biblioteker Eksempler Se http://arduino.org/libraries debounce Cookbook side 157 isdigit If(isDigit(ch)) // tjek om en variabel har værdien fra 0 til 9. Se Cookbook side 101 Seriel UART SoftSerial: Hvis fx en rx-pin ikke bruges, kan den gives pinnummer 255. Der kan laves flere soft-serial porte ( Cookbook s. 144 #include <SoftwareSerial.h> const int rxpin1 = 2; const int txpin1 = 3; Side 32 af 35
const int rxpin2 = 4; const int txpin2 = 5; SoftwareSerial gps(rxpin1, txpin1); // gps device connected to pins 2 and 3 SoftwareSerial xbee(rxpin2, txpin2); // xbee device connected to pins 4 and 5 void setup() xbee.begin(9600); gps.begin(4800); xbee.listen(); // Set xbee to be the active device Serial print / write, se skema side Cookbook side 99. Send 1 byte som byte: Serial.write(bytevalue); Der kan også skrives: myserial.print( (byte)131 ); Serial.write() expects a byte argument (8 bits) myserial.print((char)c); lowbyte highbyte Læs flere pins til 1 variabel: Serial.write(lowBYTE(intvalue)); Serial.write(highBYTE(intvalue)); int values = 0; // se Cookbook side 123 int bit = 0; for(int i=2; i <= 13; i++) bitwrite(values, bit, digitalread(i)); // set the bit to 0 or 1 depending // on value of the given pin bit = bit + 1; // increment to the next bit map Random Int value = random(599); // giver random værdi fra 0 op til 598 randnumber = random(10, 20); randum(min, max) While int i = 0; while (i < 100) // Do something!! fx en sub: flash(200); i ++; int segmentpins[] = 3, 2, 19, 16, 18, 4, 5, 17; Side 33 af 35
Globale variable void setup() for (int i=0; i < 8; i++) pinmode(segmentpins[i], OUTPUT); volatile int state = LOW; Constrain The constrain() function requires three parameters: x, a, and b where x is the number you want to constrain, a is the lower end of the range, and b is the higher end. So, the constrain() function looks at the value of x and makes sure it is within the range of a to b. If it is lower than a, it sets it to a; if it is higher than b, it sets it to b. 13 sensorval = constrain(map(analogread(a0),200,800,0,100),0,100); Therefore an Analog reading of 0 = 0 Analog reading of 100 = 0 Analog reading of 200 = 0 Analog reading of 800 = 100 Analog reading of 955 = 100 Analog reading of 1023 = 100 Analog values between 200 and 800 will produce a result between 0 and 100. Seriel skiftereg void shiftout(byte dataout) Apress beginning PDF side 127 char string1[] = "Hello!"; lcd.println(string1); //send the string to the LCD sensorval = map(analogread(a0),0,1023,0,100) map(value, fromlow, fromhigh, tolow, tohigh) int val = analogread(0); val = map(val, 0, 1023, 0, 255); analogwrite(9, val); Side 34 af 35
LED Ur i 30 Projects evil --- pdf SD-kort i Apress lego pdf, s. 114 Led Dot Matrix Apress beginning side 134. Burger 2 74HC595 Grafisk LCD Apress beginning side 246 SD-kort Apress beginning pdf side 317 RF-ID Apress beginning side pdf side 344 Færdig med apress Side 35 af 35