![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
thread
Dependencies: HCSR04 mbed-rtos mbed
Fork of MotorShield_futura by
Diff: main.cpp
- Revision:
- 3:2816fec3acee
- Parent:
- 2:7df0fc7d8d3c
diff -r 7df0fc7d8d3c -r 2816fec3acee main.cpp --- a/main.cpp Thu May 25 07:12:44 2017 +0000 +++ b/main.cpp Thu May 03 14:52:49 2018 +0000 @@ -6,11 +6,27 @@ /*---COSTANTI---*/ #define MAX 999999 //valore intero massimo utilizzabile - - #define CTRL_SIRENA D11 //D11 - pin aggancio sensore sonoro + + #define DISTANCE_CTRL 20 /*decido una distanza, in cm, per i vari controlli dell' ultrasuono, esempio utilizzo come valore + per capire quando la macchina si deve fermare*/ + + #define NUM_CICLIC_CTRL 200 /*costante indicante il numero di volte che acquisisco un valore dall'ultrasuoni prima di dicidere se sia affidabile*/ + + #define MIN_RANGE_ULTRASOUND 5 /*indica, in centimetri, il range minimo dell'ultrasuono*/ - #define DISTANCE_CTRL 10 /*decido una distanza, in cm, per i vari controlli dell' ultrasuono, esempio utilizzo come valore - per capire quando la macchina si deve fermare*/ + #define MAX_RANGE_ULTRASOUND 400 /*indica, in centimetri, il range massimo dell'ultrasuono*/ + + #define NOT_CONTROL_TIME 300 /*tempo in cui il robot esegue movimenti senza controlli da parte dei sensori*/ + + #define NUMBER_CRC 9 //numero utilizzato per controlli nell avanzamento automatico (vedi nella funzione che lo utilizza per spiegazione approfondita) + + + #define LED_AUTOMATIC PB_2 //attacco led controllo modalita automatica + + /*---COSTANTI PER GESTIONE SIRENA---*/ + #define MIN_CHECK 50 + #define PIN_SIRENA D11 //D11 - pin aggancio sensore sonoro + /*----------------------------------*/ /*---PIN BLUETHOOT---*/ /*I pin utilizzati per TX e RX sono pin morfo, a livello hardware collegare il pin TX dell HC05 al PA_12 e quello RX a PA_11 ( a livello harware vanno invertiti )*/ @@ -51,6 +67,10 @@ HCSR04 ultrasuoniDestra(DESTRA_TRIGGER, DESTRA_ECHO); /*--------------------------*/ + DigitalOut ledAutomatic(LED_AUTOMATIC); //pin in rifermineto al led controllo mod automatica + + DigitalIn sirena(PIN_SIRENA); //pin in riferimento all'aggancio del sensore sonoro + Serial pc(USBTX, USBRX); //istanzio oggetto per utilizzo monitor seriale Serial device(TX, RX); //oggetto per gestione seriale bluethoot @@ -58,6 +78,8 @@ bool flagSirena = true; //utilizzato per bloccare il robot nel caso senta una sirena bool flagAutomatic; //utilizzo per sapere se utilizzare modalita automatica o meno + + bool flagStopAvanti; /*----------------*/ /*---PROTOTIPI---*/ @@ -69,23 +91,45 @@ bool checkFermo(); void automaticProgram(); void check_sirena_thread(void const *args); - void check_stop_thread(void const *args); + void check_stop_thread(void const *args); + void check_stop_avanti(void const *args); /*---------------*/ int main() { unsigned char rx; + int distanceTemp; motorBpower.period_ms(10); //setto periodo per impulsi da inviare ai motori ( consiglio di non variare ) motorApower.period_ms(10); //setto periodo per impulsi da inviare ai motori ( consiglio di non variare ) + Thread sirenaThread(check_sirena_thread); // start Thread controllo sirena + Thread ctrlStopThread(check_stop_thread); // start Thread controllo fine processo automatico + Thread ctrlStopAvanti(check_stop_avanti); // start Thread controllo fine processo avanzamento + while(true){ if( device.readable() ) { //funzione simile alla Serial.available() di arduino, solo se il monitor e` attivo permette di utilizzarlo rx = device.getc(); //funzione simile alla Serial.read() di arduino, legge il carattere dal seriale del bluethoot //pc.printf("recived: %c \r\n",rx); //stampa a video switch(rx){ //in base alla lettera che riceve sa cosa deve fare case 'a': - avanti(); + flagStopAvanti = true; /*il thread check_stop_avanti viene avviato appena tale flag diventa true*/ + /*a causa di problemi riscontrati con l'utilizzo dell'ultrasuono si e' deciso di ripere l'operazione di acquisizione + dati dall'ultrasuono per piu' volte (tante quante NUMBER_CRC) in modo da essere sicuri del valore ottenuto*/ + for(int j = 0; j < NUMBER_CRC && flagStopAvanti; j++){ + distanceTemp = MAX; + for( int i = 0; i < NUM_CICLIC_CTRL && ( distanceTemp < MIN_RANGE_ULTRASOUND || distanceTemp > MAX_RANGE_ULTRASOUND && flagStopAvanti ); i++ ){ //questo perche il range dell'ultrasuono usato va da 2 cm a 4 m ( 400 cm ) + ultrasuoniAvanti.start(); + distanceTemp = ultrasuoniAvanti.get_dist_cm(); + //wait_ms(10); + } + while( distanceTemp > 8 && flagStopAvanti ){ + avanti(); + ultrasuoniAvanti.start(); + distanceTemp = ultrasuoniAvanti.get_dist_cm(); + } + fermo(); + } break; case 'b': indietro(); @@ -101,7 +145,9 @@ break; case 'f': flagAutomatic = true; + ledAutomatic = 1; //accensione led mod automatica automaticProgram(); //funzione pilota automatico + ledAutomatic = 0; //spegnimento led break; } } @@ -115,9 +161,6 @@ int distanceDx, distanceSx; - Thread sirenaThread(check_sirena_thread); // start Thread controllo sirena - Thread ctrlStopThread(check_stop_thread); // start Thread controllo sirena - fermo(); while(flagAutomatic){ //flag modificabile dal thread che aspetta il segnale di stop @@ -138,13 +181,15 @@ if( checkFermo() && flagSirena && flagAutomatic ){ /*funzione utilizzata per leggere un valore attendibile ( nel range dell ultrasuono ). se dopo 100 tentativi il valore non e' ancora attendibile allora esco dal controllo in modo da non rimanere bloccato*/ - for( int i = 0; i < 100 && ( distanceDx < 2 || distanceDx > 400 ); i++ ){ //questo perche il range dell'ultrasuono usato va da 2 cm a 4 m ( 400 cm ) + distanceDx = MAX; + distanceSx = MAX; + for( int i = 0; i < NUM_CICLIC_CTRL && ( distanceDx < MIN_RANGE_ULTRASOUND || distanceDx > MAX_RANGE_ULTRASOUND ); i++ ){ //questo perche il range dell'ultrasuono usato va da 2 cm a 4 m ( 400 cm ) ultrasuoniDestra.start(); distanceDx = ultrasuoniDestra.get_dist_cm(); //wait_ms(10); } - for( int i = 0; i < 100 && ( distanceSx < 2 || distanceSx > 400 ); i++ ){ //questo perche il range dell'ultrasuono usato va da 2 cm a 4 m ( 400 cm ) + for( int i = 0; i < NUM_CICLIC_CTRL && ( distanceSx < MIN_RANGE_ULTRASOUND || distanceSx > MAX_RANGE_ULTRASOUND ); i++ ){ //questo perche il range dell'ultrasuono usato va da 2 cm a 4 m ( 400 cm ) ultrasuoniSinistra.start(); distanceSx = ultrasuoniSinistra.get_dist_cm(); //wait_ms(10); @@ -153,16 +198,25 @@ /*controllo se il valori valori di uscita dalle iterazioni sono attendibili ( nel range ) se non soddisfano i criteri allora li setto al valore MAX in modo che i seguenti controlli non li prendano in considerazione*/ - if( distanceSx < 2 || distanceSx > 400 ) + if( distanceSx < MIN_RANGE_ULTRASOUND || distanceSx > MAX_RANGE_ULTRASOUND ){ distanceSx = MAX; + distanceDx = MAX; + continue; + } - if( distanceDx < 2 || distanceDx > 400 ) + if( distanceDx < MIN_RANGE_ULTRASOUND || distanceDx > MAX_RANGE_ULTRASOUND ){ distanceDx = MAX; + distanceSx = MAX; + continue; + } - pc.printf("distanceSx: %d distanceDx: %d\r\n",distanceSx, distanceDx); + /*if( distanceDx == MAX && distanceSx == MAX ) //mod veloce + continue;*/ + + //pc.printf("distanceSx: %d distanceDx: %d\r\n",distanceSx, distanceDx); //in base ai valori letti capisco da che lato e' piu vicino la superficie piana e in base a cio sono da che parte girare - if( distanceSx > distanceDx ){ + if( distanceSx > distanceDx && distanceSx != MAX){ sinistra(); wait_ms(1000); @@ -170,12 +224,12 @@ distance = ultrasuoniDestra.get_dist_cm(); //pc.printf("sinistra: %d \r\n",sinistraDis); while( distance >= DISTANCE_CTRL && flagSirena && flagAutomatic ){ //il robot continua la rotazione per evitare l' ostacolo finche l' ultrasuono di destra lo avverte di aver trovato una superficie piana - ultrasuoniDestra.start(); + ultrasuoniDestra.start() ; distance = ultrasuoniDestra.get_dist_cm(); //pc.printf("distance: %d \r\n",distance); } } - else{ + else if( distanceDx != MAX ){ destra(); wait_ms(1000); @@ -189,38 +243,72 @@ } } - wait_ms(200); + wait_ms(NOT_CONTROL_TIME); fermo(); } } } } +void check_stop_avanti(void const *args) +{ + /*questo thread ha il compito di attendere che l utente richieda lo stop del mezzo, quando cio avviene il thread setta il flag a + false e interrompe sia se stesso che la funzione avanti*/ + unsigned char rx; + while(true) + while( flagStopAvanti ) + if( device.readable() ) { //funzione simile alla Serial.available() di arduino, solo se il monitor e` attivo permette di utilizzarlo + rx = device.getc(); //funzione simile alla Serial.read() di arduino, legge il carattere dal seriale del bluethoot + if( rx == 'e' ) + flagStopAvanti = false; + } +} + void check_stop_thread(void const *args) { /*thread che controlla se l'utente via dispositivi ha chiesto lo stop del proamma automatico*/ unsigned char rx; - while(true) { - if( device.readable() ) { //funzione simile alla Serial.available() di arduino, solo se il monitor e` attivo permette di utilizzarlo - rx = device.getc(); //funzione simile alla Serial.read() di arduino, legge il carattere dal seriale del bluethoot - if( rx == 'g' ) - flagAutomatic = false; - } - } + while(true) + while( flagAutomatic ) + if( device.readable() ) { //funzione simile alla Serial.available() di arduino, solo se il monitor e` attivo permette di utilizzarlo + rx = device.getc(); //funzione simile alla Serial.read() di arduino, legge il carattere dal seriale del bluethoot + if( rx == 'g' ) + flagAutomatic = false; + } } void check_sirena_thread(void const *args) { - /*thread che controlla sempre il pin dedicato alla sirena, se il pin diventa alto comunica il cambiamento - con un flag al main che si adatta alla situazione*/ - DigitalIn in(CTRL_SIRENA); - while(true){ - int val = in.read(); + /*la funzione controlla il pin dedicato al sensore sonoro per un lasso di tempo fisso. + Se in questo lasso di tempo riceve abbastanza valori che li indicano una sirena allora esce direttamente + dalla struttura di controllo e blocca il robot, se in questo lasso invece dopo un po non riceve alcun valore + attendibile allora esce della struttura di controllo prima del previsto e ricomincia i suo controlli da capo.*/ + int val, contaHigh = 0, contaLow = 0; + int aumentoLow = 100; //rispetto al controllo dello stato HIGH, lo stato LOW e' controllato per piu' volte + while(true) { + for(int i = 0; i < 500 && ( contaHigh < MIN_CHECK ) && ( contaLow < MIN_CHECK+aumentoLow ); i++){ + val = sirena.read(); + //pc.printf("recived: %d \r\n",conta); //stampa a video + if( val == 1 ) + contaHigh++; + else + if( val == 0 ) + contaLow++; + wait_ms(5); + } + if( contaLow >= MIN_CHECK+aumentoLow ) + flagSirena = true; + else + if( contaHigh >= MIN_CHECK ) + flagSirena = true; //mettere FALSE dopo istallazione sensore sonoro + contaHigh = 0; + contaLow = 0; + /*val = sirena.read(); if( val == 1 ) flagSirena = false; else - flagSirena = true; - } + flagSirena = true;*/ + } } bool checkFermo() @@ -269,7 +357,7 @@ { motorBdirection = 1; motorAdirection = 1; - motorBpower.pulsewidth(0.007); // 100% + motorBpower.pulsewidth(0.007); // 700% motorApower.pulsewidth(0.01); // 100% }