Analoge Input 5 6 7

7 replies [Last post]
Roeland 2.0
Offline
Member since: 2012-04-03

Beste forumleden,

Ik probeer 8 nabijheidssensoren aan te sluiten op het dwengo-bord.
De eerste v5 vormen geen probleem, maar de analoge ingangen 5 tot en met 7 blijken niet te werken.

Ik maak gebruik van de standaard-dwengo-bibliotheken met zelf-geschreven functies opdat het LCD-scherm zou blijven werken tijdens het testen.

Aanpassingen in dwengoADC.c
Deze functies werden ook toegevoegd aan het dwengoADC.h bestand

  1. void setAN567(void){
  2. LATA = 0xFF;
  3. OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_6_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 0b0111);
  4. }
  5. void resetAN567(void){
  6. LATA = 0xFF;
  7. OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_6_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 0b1010);

aangepaste versie van readADC

  1. int readADC(BYTE address) {
  2. int data;
  3.  
  4. // Choosing ADC channel (override ADC_CH0)
  5. switch(address) {
  6. case 0: SetChanADC(ADC_CH0); break;
  7. case 1: SetChanADC(ADC_CH1); break;
  8. case 2: SetChanADC(ADC_CH2); break;
  9. case 3: SetChanADC(ADC_CH3); break;
  10. case 4: SetChanADC(ADC_CH4); break;
  11. case 5: SetChanADC(ADC_CH5); break;
  12. case 6: SetChanADC(ADC_CH6); break;
  13. case 7: SetChanADC(ADC_CH7); break;
  14. default: return -1; // non existing channel
  15. }

Wanneer ik nu volgend programma laat draaien, dan blijft het LCD-scherm werken.
Bij het aansluiten van sensoren is er een grote verandering in de waarden van AN0-AN4. Maar de waarden van AN5-AN7 veranderd van 1 naar 3. De waarde reageert ook NIET op nabijheid bij deze 3 laatste analoge inputs.

  1. while(TRUE) { // do forever
  2. //INTCON2bits.NOT_RBPU = 0; //enabe de knoppen !! (testfase)
  3. clearLCD();
  4.  
  5. // Uitlezen sensoren + berekenen lijnwaarde + aansturen LCD-scherm + aansturen LEDS
  6. LEDS = 0b00000000;
  7. j = 128;
  8. isLost = true;
  9. setAN567(); //maak de analoge ingangen 5-7 tijdelijk beschikbaar => LCD-scherm onzichtbaar !!
  10. for(i=0;i<8;i = i + 1) {
  11. ADC[i] = readADC(i);
  12. if(readADC(i) > thresholdValue){// uitlezing
  13. sensor[i] = false; // detectie wit
  14. }
  15. else{
  16. sensor[i] = true; // detectie zwart
  17. isLost = false; // robot detecteerd iets. Dus niet verdwaald
  18. LEDS = LEDS + j; // LEDS geven indicatie van sensoren links = 128 rechts = 1
  19. }
  20. j = j / 2;
  21. }
  22. resetAN567(); // maak de analoge ingangen 5-7 weer onbeschikbaar => LCD-scherm weer zichtbaar
  23.  
  24. for(i = 0; i < 8; i = i + 1){
  25. appendIntToLCD(ADC[i]);
  26. appendStringToLCD(" ");
  27. }
  28. }

kan iemand me helpen?

ter info:
voor deze code komt nog deze initialisatie (niet zelf geschreven)

  1. // start of initializations: DO NOT EDIT
  2. initBoard();
  3. initADC();
  4. initMotors();
  5. backlightOn();
  6. stopMotors();
  7. delay_ms(10); // wait a bit after initialisation
  8. // end of initializations
  9.  
  10. // start procedure necessary for the robot competition: DO NOT EDIT
  11. // robot has to move to the control loop when pressing switch S (new version) or S4 (old version)
  12. appendStringToLCD("(S)tart me");
  13. while(!started) {
  14. stopMotors();
  15. if(SW_S == PRESSED) {
  16. started = TRUE;
  17. } else {
  18. delay_ms(50);
  19. }
  20. }
  21. // 5 seconds waiting
  22. clearLCD();
  23. appendStringToLCD("Start counting");
  24. LEDS = 0;
  25. for(i=0;i<5;i++) {
  26. LEDS *= 2;
  27. LEDS += 1;
  28. delay_s(1);
  29. } // end of starting procedure
  30. clearLCD();
  31. appendStringToLCD("Race!");
  32.  
  33. // routines for servo control DO NOT EDIT
  34. // servo pins
  35. INTCON2bits.NOT_RBPU = 1; // disable internal pull-ups: SWITCHES WON'T WORK ANYMORE
  36. TRISBbits.TRISB5 = 0; // set RB5 as output
  37. PORTBbits.RB5 = 0; // initialize with 0
  38.  
  39. // Timer 1 interrupt example, control one servo on pin RD0
  40. // timings servo has to be within 0.7 ms up to 2.3 ms
  41. // 0.7 ms: timer 1 interrupt after 83.333ns*8*(65536-64536) = 0.7ms (64486 = 0xFBE6)
  42. // 2.3 ms: timer 1 interrupt after 83.333ns*8*(65536-62086) = 2.3ms (62086 = 0xF286)
  43. timerServo = MIN_TIMER_SERVO; // in left position
  44. PIR1bits.TMR1IF = 0;
  45. RCONbits.IPEN = 1;
  46. RCONbits.SBOREN = 0; // BOR = off
  47. TMR1H = (timerServo & 0xFF00) >> 8; // keep most significant byte
  48. TMR1L = timerServo & 0x00FF; // keep least significant byte
  49. T1CON = 0b00110001; // 48Mhz/4, prescaler 1/8
  50. INTCONbits.GIEH = TRUE; // GIEH = TRUE
  51. IPR1bits.TMR1IP = 1;
  52. PIE1bits.TMR1IE = 1;
Francis
Offline
Member since: 2009-04-16

Probeer eens LATA te vervangen door TRISA. Het is met TRISA dat je de pinnen van poort A als ingang instelt (dat is blijkbaar een foutje in de ADC-bibliotheek). En gebruik ook 0b0110 i.p.v. 0b0111 (want er staat daar een uitzondering bij die ik nog eens moet nazien).
Bekijk ook volgende pagina voor meer uitleg: http://www.dwengo.org/nl/node/229

Roeland 2.0
Offline
Member since: 2012-04-03

Ik heb ondertussen de tijd gevonden dit te testen.

LATA door TRISA vervangen => nog steeds hetzelfde
0111 door 0110 vervangen => nog steeds hetzelfde

Als ik de waarden uitschrijf op het LCD-scherm die hij binnenpakt (gedeeld door 10, anders kan het er niet op)krijg ik typisch iets als volgt:
5 5 5 5 5 0 0 0
(links = AN0; rechts is AN7)
het lijkt wel of die poort niet gevoed wordt ofzo. De sensoren zijn nochtans goed aangesloten

Francis
Offline
Member since: 2009-04-16

Wat gebeurt er als je jouw LCD-scherm ervan haalt en vervolgens i.p.v. het LCD-scherm de LEDs gebruikt om output te geven. Zet LED0 eens aan wanneer sensor 0 > 500 en anders zet je LED0 uit, hetzelfde voor LED1, LED2 etc... Het LCD-scherm en de ADC-kanalen zitten immers op dezelfde pinnen.

Roeland 2.0
Offline
Member since: 2012-04-03

Dit is de code die ik heb ingeladen:

  1. while(TRUE) { // do forever
  2. clearLCD();
  3. initADC();
  4. LEDS = 0b00000000;
  5.  
  6. j = 1;
  7. for(i=0;i<8;i = i + 1) {
  8. ADC[i] = readADC(i);
  9. if(readADC(i) < 500){// uitlezing
  10. sensor[i] = false; // detectie wit
  11. }
  12. else{
  13. sensor[i] = true; // detectie zwart
  14. LEDS = LEDS + j;
  15. }
  16. j = j * 2;
  17. }
  18.  
  19.  
  20.  
  21. delay_ms(500);
  22.  
  23. }
  24. }

met

  1. void initADC() {
  2. TRISA= 0xFF; // set all A to inputs
  3. OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_6_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 0b0110); // Configuring ADC
  4. }

Zowel geprobeerd met TRISA als LATA
De eerste 5 LEDS lichten op bij het aansluiten van de sensoren, de laatste 3 niet. Heb ook al getest of de LEDS niet kapot zijn door andere LEDS te laten branden...

als het niet lukt vanop afstand om dit probleem om te ossen kom ik zeker eens langs op de laatste sessie van de WELEK-competitie. We zouden onze 8 sensoren namelijk willen gebruiken in ons algoritme :)

Francis
Offline
Member since: 2009-04-16

De aanpassingen die je doet lijken me alleszins correct, maar er moet nog een kleine foutje zitten ergens. Ik weet namelijk van anderen dat gelijkaardige aanpassingen wel werken.

Ik zal het dinsdagavond na kijken als je langskomt. Dan kunnen we ook de juiste oplossing hier posten.

Roeland 2.0
Offline
Member since: 2012-04-03

Oké, hier is dan de oplossing voor het probleem, thx 2 Francis.

Om één of andere reden werkt analoog kanaal 5, 6 en 7 niet, zelfs niet as het LCD-scherm niet aangesloten is en niet wordt aangeroepen in de code.

Daarom werd er voor gekozen andere vrije kanalen te gebruiken. Voor een autonome robot zijn de drukknoppen niet nodig, dus we kozen ervoor de kanalen AN8, AN10 en AN11 te gebruiken voor de 3 extra analoge ingangen.

Dit is hoe de code er nu uitziet:

dwengoADC.c (opgepast, ook het header-bestand aanpassen!)

  1. #include <adc.h>
  2. #include <p18f4550.h>
  3. #include <delays.h>
  4. #include "dwengoADC.h"
  5. #include "dwengoDelay.h"
  6.  
  7.  
  8. void initADC() {
  9. TRISA = 0xFF; // set all A to inputs
  10. OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_6_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 0b1010);
  11. }
  12.  
  13. int readADC(BYTE address) {
  14. int data;
  15. switch(address) {
  16. case 0: SetChanADC(ADC_CH0); break;
  17. case 1: SetChanADC(ADC_CH1); break;
  18. case 2: SetChanADC(ADC_CH2); break;
  19. case 3: SetChanADC(ADC_CH3); break;
  20. case 4: SetChanADC(ADC_CH4); break;
  21. case 5: SetChanADC(ADC_CH8); break;
  22. case 6: SetChanADC(ADC_CH10); break;
  23. case 7: SetChanADC(ADC_CH11); break;
  24. default: return -1;
  25. }
  26.  
  27. delay_us(125);
  28. ConvertADC();
  29. while (BusyADC());
  30. data = ReadADC();
  31.  
  32. return data;
  33. }
  34.  
  35. void setAN567(void){
  36. TRISA = 0xFF;
  37. OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_6_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 0b0001);
  38. }
  39.  
  40. void resetAN567(void){
  41. TRISA = 0xFF;
  42. OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_6_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 0b1010);
  43. }

En de laatste 2 functies dien je dan als volgt te gebruiken in je main-bestand. Je moet setAN567 gebruiken net voor de start van de inlezing en resetAN567 aanroepen net na de inlezing. Zo wordt je LCD-scherm héél kort uitgeschakeld, maar blijft het wel heelde tijd zichtbaar. een voorbeeld:

  1. while(TRUE) {
  2. clearLCD();
  3.  
  4. LEDS = 0b00000000;
  5.  
  6. j = 1;
  7. setAN567();
  8. for(i=0;i<8;i = i + 1) {
  9. ADC[i] = readADC(i);
  10. if(ADC[i] < 500){
  11. sensor[i] = false;
  12. }
  13. else{
  14. sensor[i] = true;
  15. LEDS = LEDS + j;
  16. }
  17. j = j * 2;
  18. }
  19. resetAN567();
  20.  
  21. for(i = 0; i < 8; i = i + 1){
  22. appendIntToLCD(ADC[i]/100);
  23. appendStringToLCD(" ");
  24. }
  25.  
  26. delay_ms(500);
  27. }
Francis
Offline
Member since: 2009-04-16

Nog één kleine aanvulling, die TRISA = 0xFF kan je in principe weglaten, die hoeft daar niet te staan en je zou zelfs problemen krijgen met de motoren.

veel succes.

Syndicate content