/* * GccApplication1.c * * Created: 2022-05-09 17:06:12 * Author : ba3187ho-s */ #define F_CPU 1000000UL #include #include #include #include #include #include "lcd.h" #define D0 eS_PORTB0 #define D1 eS_PORTB1 #define D2 eS_PORTB2 #define D3 eS_PORTB3 #define D4 eS_PORTB4 #define D5 eS_PORTB5 #define D6 eS_PORTD5 #define D7 eS_PORTD6 #define RS eS_PORTD2 #define EN eS_PORTD4 //variabler volatile uint8_t noDigits = 0; volatile uint16_t ms = 0; volatile uint8_t sec = 0; volatile uint8_t min = 0; volatile uint16_t msSaved = 0; volatile uint8_t secSaved = 0; volatile uint8_t minSaved = 0; char buffer_ms[16]; char buffer_sec[16]; char buffer_min[16]; volatile uint8_t timeCounter = 0; // Variabler, tilldelade med vilken bitplats de har. uint16_t AIN1 = 0; // PD0 uint16_t AIN2 = 6; // PB6 - PWM uint16_t BIN1 = 1; // PD1 uint16_t BIN2 = 7; // PB7 - PWM // Variabler, tilldelade vilket värde som ska vara för PWM - (ska vara volotile?) uint16_t pulseNBR1 = 5 ; // Värde för pulse - PWM uint16_t pulseNBR2 = 5 ; // Värde för pulse - PWM uint16_t periodNBR = 10; // Värde för perioden - PWM volatile uint16_t nbr,nbr1,nbr2; //variabler för riktningsändring uint8_t straight =0; uint8_t left =0; uint8_t right =0; // Variabler för avläsning av sensorvärde (0 / 1) uint8_t SF1 = 0; uint8_t SF2 = 0; uint8_t SF3 = 0; uint8_t SL2 = 0; uint8_t SL1 = 0; uint8_t SR2 = 0; uint8_t SR1 = 0; uint16_t avaragevalue = 0; uint8_t counter = 0; volatile uint16_t nbr; // Vilken sida bilen kör av från tejpen // Höger 1 , Vänster 0 char side; uint8_t state = 0; // Variabler för om knappen har tryckts ner volatile uint8_t greenButton = 0; volatile uint8_t redButton = 0; volatile uint8_t lengthOfButtonGREEN = 0; volatile uint8_t lengthOfButtonRED = 0; //Variabel för att målet är nått uint8_t goal_is_reached = 0; void init_stopwatch() { TCCR1B |= (1<999){ ms=0; sec++; if(sec>59){ sec=0; min++; } } } // Placera koden för initiering här, kommer köras en gång void setUp (){ // Tilldelning av input/output av olika pins DDRA |= 0x00; // Sensorer 0b00000000 (alla ingångar på ADC) DDRB |= 0xFF; DDRD |= 0b01111111; // Dual H-Bridge 0b00000011 // Initierar PWM TCCR3A |= 0b10100010; TCCR3B |= 0b00011100; } // Tilldela puls-värde, nbr1 för Motor 1, nbr 2 för Motor 2 void set_pulse(int nbr1,int nbr2){ OCR3A = nbr1; OCR3B = nbr2; TCNT3 = 0; } void set_period (int nbr){ ICR3 = nbr; } //Alla motorfunktioner void driveForward (){ // Skicka värde genom AIN1, AIN2, BIN1, BIN2, till Dual H-Bridge set_period(18); set_pulse(8, 8); // AIN - Motor 1 PORTD |= (1< möjlighet till högersväng right = 3; right1 =1; } } // om sensor SF2 returnerar 1 --> möjlighet till att köra rakt fram if ((SF2 == 1)||(SF1 == 1)||(SF3 == 1)) { straight = 2; straight1 =1; } } else if (SR1 == 1) { right = 3; right1 =1; // sensor SR3 returnerar 1, möjlighet till högersväng while (((SR2 == 1) || (SR1 == 1)) && goal_is_reached==0) { read_sensors(); driveForward(); if (SL1 == 1) { left = 1; left1 =1; // om sensor SL1 returnerar 1 --> möjlighet till vänstersväng } } if ((SF2 == 1)||(SF1 == 1)||(SF3 == 1)) { // om sensor SF2 returnerar 1 --> möjlighet till att köra rakt fram straight = 2; straight1 =1; } } sum = straight1+left1+right1; // sum = 1 om det finns bara en riktning att ta // sum > 1 om det finns fler än en riktning att ta } void ChangingDirection() { // In denna funktion, ska man checka om sum = 1 eller sum >1 // sum = 1, bara en riktning att ta --> bilen ska ta den riktning som är tillgänglig // sum > 1, en random funktion drar igång, genererar ett tal från 1 till 3. stopEngine(); if ((sum == 1) && (goal_is_reached==0)){ if(left == 1){ turningLeft(); } else if (right == 3){ turningRight(); } else { driveForward(); } } else if((sum > 1) && (goal_is_reached==0)){ // rand funktion: uint8_t number = (ms % 3)+1; while((number != left)&&(number != right )&&(number != straight)){ number = (number % 3) +1; } // funktion som genererar ett tal från 1 till 3 // tanken här är att randfunktion genererar talet från 1 till 3, vilket i sin tur ska matcha //(lika med)EN AV VARIABLER (left, right, straight), //om det matchar -->bilen svänga till den riktning //om det matchar inte -->genererar ny tal igen. if(left == number && goal_is_reached==0){ turningLeft(); } else if (right == number && goal_is_reached==0){ turningRight(); } else if (straight == number && goal_is_reached==0){ driveForward(); } } if (goal_is_reached==0) { driveForward(); } // variabler för riktningar nollställas för de kommande riktningsändringar straight = 0; left = 0; right = 0; sum = 0; left1 =0; right1= 0; straight1 =0; } //Läser av GRÖN knapp void readButtonGREEN (){ // Kollar om knappen har blivit nedryckt if ((PIND & 0b10000000) == 0b10000000){ //För varje gång som den identifierar knappen nedtryckt¨, öka värdet på lengthOfButton lengthOfButtonGREEN++; } // Om knappen varit nedtryckt länge än en viss tid, identifiera detta som att knappen definitivt har blivit tryckt if(lengthOfButtonGREEN>3){ lengthOfButtonRED = 0; lengthOfButtonGREEN = 0; greenButton = 1; redButton = 0; goal_is_reached = 0; timeCounter = 0; ms = 0; sec = 0; min = 0; Lcd8_Clear(); } } //Läser av RÖD knapp void readButtonRED (){ if ((PINC & 0b00000001) == 0b00000001){ //För varje gång som den identifierar knappen nedtryckt¨, öka värdet på lengthOfButton lengthOfButtonRED++; } if(lengthOfButtonRED>3){ lengthOfButtonRED = 0; lengthOfButtonGREEN = 0; greenButton = 0; redButton = 1; stopEngine(); goal_is_reached = 1; } } void countDigit(int n){ if ((n/10) == 0){ noDigits = 1; } else if (n/10 >= 1){ noDigits = 2; } } void writeTime(){ itoa(ms, buffer_ms, 10); itoa(min, buffer_min, 10); itoa(sec, buffer_sec, 10); Lcd8_Set_Cursor(1,1); Lcd8_Write_String("Time: "); Lcd8_Set_Cursor(1,8); Lcd8_Write_String(buffer_min); countDigit(sec); if(noDigits == 1){ Lcd8_Set_Cursor(1,9); Lcd8_Write_String(":0"); Lcd8_Set_Cursor(1,11); Lcd8_Write_String(buffer_sec); } else if(noDigits > 1) { Lcd8_Set_Cursor(1,9); Lcd8_Write_String(":"); Lcd8_Set_Cursor(1,10); Lcd8_Write_String(buffer_sec); } Lcd8_Set_Cursor(1, 12); Lcd8_Write_String(":"); Lcd8_Set_Cursor(1, 13); Lcd8_Write_String(buffer_ms); } void writeSavedTime(){ msSaved = ms; secSaved = sec; minSaved = min; if (timeCounter==0) { itoa(msSaved, buffer_ms, 10); itoa(minSaved, buffer_min, 10); itoa(secSaved, buffer_sec, 10); Lcd8_Set_Cursor(2,1); Lcd8_Write_String("Time: "); Lcd8_Set_Cursor(2,8); Lcd8_Write_String(buffer_min); countDigit(sec); if(noDigits == 1){ Lcd8_Set_Cursor(2,9); Lcd8_Write_String(":0"); Lcd8_Set_Cursor(2,11); Lcd8_Write_String(buffer_sec); } else if(noDigits > 1) { Lcd8_Set_Cursor(2,9); Lcd8_Write_String(":"); Lcd8_Set_Cursor(2,10); Lcd8_Write_String(buffer_sec); } Lcd8_Set_Cursor(2, 12); Lcd8_Write_String(":"); Lcd8_Set_Cursor(2, 13); Lcd8_Write_String(buffer_ms); timeCounter++; } } int main(void) { // Initierar, körs en gång. setUp(); stopEngine(); init_adc(); init_stopwatch(); Lcd8_Init(); Lcd8_Set_Cursor(1,1); while (1) { // Läs av om någon knapp trycks readButtonGREEN(); readButtonRED(); //Läs av sensor read_sensors(); current_state(); if (redButton==1){ writeSavedTime(); } if((greenButton==1) && (redButton==0)){ if(!PossibilityForDirectionChange()){ switch (state) { case 0: stopEngine(); break; case 1: driveForward(); break; case 2: adjustToLeft(); break; case 3: adjustToRight(); break; case 4: turnAroundLeft(); break; case 5: turnAroundRight(); break; default: turnAroundLeft(); } } if(PossibilityForDirectionChange()){ LookingforDirection(); ChangingDirection(); } } } }