Go Down

Topic: Ardutester - Arduino Component Tester (INCOMPLETO) (Read 227590 times) previous topic - next topic

leo72


Una richiesta agli esperti:

Quanto è da considerare affidabile il delay() di Arduino? (Idem per il delayMicroseconds())

Affidabile? Forse intendi "preciso". Quanto è preciso il risonatore ceramico esterno. Molto poco. In genere si parla di +/- 10%.
Se però stai pensando allo standalone dell'ArduTester, devi senz'altro metterci un quarzo, ne guadagni tantissimo in precisione appunto.

pighixxx

Si volevo intendere "preciso".
Cosa ne dici della soluzione di Markus Reschke?

Code: [Select]
void MilliSleep(uint16_t Time)
{
  uint32_t               Cycles;        /* timer cycles */
  uint8_t                Timeout;       /* compare value */
  uint8_t                Mode;          /* sleep mode */

  /*
   *  calculate stuff
   */

  /*
      Using timer prescaler of 1024 (maximum):
        MCU frequency  1MHz    8MHz   16MHz
        timer cycle    1024µs  128µs  64µs

      We don't compensate the binary to decimal offset and also not the time
      required for the processing loop, because it would make things much more
      complicated and we don't need exact timing here.
   */

  /* calculate required timer cycles (prescaler 1024) */
  Cycles = Time * (CPU_FREQ / 1000000);      /* timer cycles based on MCU frequency */


  /*
      After returning from the power down or power save sleep modes the
      main oscillator needs following start-up times to stabilize:
      - crystal oscillator:  16k cycles
      - ceramic resonator:   1k or 256 cycles
      - internal RC osc.:    6 cycles

      In power save mode the external oscillator should be turned off. But if
      timer2 is running in synchronous mode the oscillator keeps running. Even
      though we have to consider the start-up time, Weird, isn't it?
   */

  Mode = Config.SleepMode;              /* get requested sleep mode */

  /* compensate oscillator start-up */
  if (Mode == SLEEP_MODE_PWR_SAVE)
  {
    uint32_t        Value;

    Value = Cycles / 256;               /* calculate loop runs */
    Value++;                            /* fix offset by division */
    /* multiply with startup cycles equivalent to timer cycles */
    Value *= (OSC_STARTUP / 1024);      /* overhead cycles */

    if (Cycles > Value)            /* we are able to compensate */
    {
      Cycles -= Value;                  /* subtract overhead cycles */
    }
    else                           /* no way to compensate */
    {
      /* idle mode doesn't require oscillator start-up after wake-up */
      Mode = SLEEP_MODE_IDLE;           /* change sleep mode to Idle */
    }
  }


  /*
   *  setup timer
   */

  TCCR2B = 0;                      /* disable timer */
  TCCR2A = (1 << WGM21);           /* set CTC mode */
  TIMSK2 = (1 << OCIE2A);          /* enable interrupt for OCR0A match */

  set_sleep_mode(Mode);            /* set sleep mode */


  /*
   *  processing loop
   *  - sleep for several intervals until requested time is reached
   */

  while (Cycles > 0)
  {
    wdt_reset();              /* reset watchdog */

    /* get timeout */
    if (Cycles > 255) Timeout = 255;
    else Timeout = Cycles;
    Cycles -= Timeout;
    Timeout--;                     /* interrupt is triggered by cycle after match */
    /* todo: what happens if Timeout is 0? */

    /* update timer */
    TCNT2 = 0;                     /* set counter to 0 */
    OCR2A = Timeout;               /* set value to compare with (timeout) */

    /* sleep */
    /* enable timer by setting clock prescaler to 1024 */
    TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20);
    sei();                                   /* enable interrupts */
    sleep_mode();                            /* and sleep */   

    /* after wakeup */
    cli();                         /* disable interrupts */
  }
}


Il problema standalone sarà di Michele  XD

testato

Fermo restando che in questo algoritmo lui fa anche altre cose, tipo controlla se è appena uscito da sleep, si muove in base ai fuse, perche gestisce diverse vel clock, ed altro, alla fine USA cm un metodo bloccante e deve farlo perche non ha il magico delay a disposizione, resta cmq il discorso precisione perché c'è poco da fare.
La domanda quindi è per cosa usi questo delay ? Influirà e di quanto sul risultato del valore dei componenti ? Il resto credo a noi non serva visto che si usa su un Arduino standard, quindi clock fisso.
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

leo72

In questo codice mi pare manchi il setup del watchdog. E poi non ho capito cosa stia facendo con il timer 2, il watchdog, e lo sleep. Sta cercando di fare un millis che vada anche con il chip in sleep?

Ma tu che necessità hai?

pighixxx

#364
Jul 06, 2013, 04:26 pm Last Edit: Jul 06, 2013, 04:30 pm by pighixxx Reason: 1
I Delay sono critici ed importanti per una buona lettura del componente. Non che adesso non sia preciso ma più i delay sono precisi più le letture sono accurate.

@Leo
Da quello che ho capito fa un delay con il chip in sleep, utilizzando l'oscillatore interno. utilizzando in qualche maniera lo sleep.

edit
Quasi quasi gli scrivo.

leo72

Pighi, non stare a preoccuparti molto di questa cosa.
Con uno standalone con un quarzo esterno al posto del risonatore dell'Arduino avrai una precisione 10 volte maggiore nei tempi, e di conseguenza nei delay, che ti ricordo sono basati sul calcolo dell'overflow del timer 0. Quindi un qualcosa che prende la frequenza dal sistema. Ora, sull'Arduino, tale fonte di clock è appunto quel risonatore sulla schedina. Ma con un quarzo migliora molto.

pighixxx

E' perché mi avanzava un po' di tempo  :D

A parte gli scherzi, sto rifinendo il tutto e ci tenevo a fare 'sti ritocchini. Nel frattempo ho sostituito i vari delay nel firmware con delle funzioni in modo da poterli aggiornare quando si vuole.

PaoloP

La presenza del quarzo era il motivo per cui volevo testare la 2009. Ma li c'è il problema del led e resistenza sul pin 13 che sballa le misure.

pighixxx

Promuoverò una campagna per rimuovere il led sul pin 13 dall'Arduino  :smiley-mr-green:

http://www.instructables.com/id/Remove-LED-from-Arduino-Board/

cece99

Non ho capito come mai il Led pin 13 causa problemi O.o
Il Vero Programmatore non ha bisogno di manuali sull'assembler, sono<br />  sufficienti i data sheet dei microprocessori.

leo72

Fino alla versione R2 della Uno e sulla precedente 2009 il led è alimentato direttamente dal pin con una resistenza. Quindi consuma corrente erogata dal pin. Sulla Uno R3 è invece pilotato da un op-amp per cui non disturba più

leo72


La presenza del quarzo era il motivo per cui volevo testare la 2009. Ma li c'è il problema del led e resistenza sul pin 13 che sballa le misure.

Non conosco bene come funziona l'Ardutester ma immagino che cambiare pin non si possa, vero? :-)

pighixxx

Come suggerito da Paolo ci sarebbe la possibilità di utilizzare la PORTD invece della PORTB ma sono in qualsiasi caso dolori.  :D

PaoloP

La comodità della porta B è che i pin mappati sono quelli che vanno dall'8 al 13, mentre per la porta D sono quelli dall'1 al 7. Nel secondo caso, manipolando la porta si dovrebbe aggiustare sempre il tiro quando si usa la seriale. Quindi lettura dello stato dei pin della seriale e riscrittura dell'intera porta compresi due pin iniziali. Giusto? ma se cambia lo stato della seriale tra la lettura e la scrittura?
Insomma... dolori.

leo72

Sì ma con PORTB avete PB6 e PB7 occupati dal quarzo/risonatore, sull'Arduino. Per cui in teoria voi dovreste usare solo 6 pin di quella porta. Se usate PORTD e saltate PD0 e PD1 (i pin della seriale) avete sempre 6 pin liberi.

Go Up