Show Posts
Pages: 1 ... 4 5 [6] 7
76  Using Arduino / Programming Questions / Re: Reading width of pulses on: March 05, 2011, 10:29:03 am
use a pin interrupt like this:


#define INT_PIN 3  //input pulse pin

extern volatile unsigned long timer0_millis;
volatile unsigned long t, now, prev;

void setup() {
  //init interrupt
  pinMode(INT_PIN, INPUT);
  attachInterrupt(1, PulseInterrupt, FALLING);  //0 = digital pin 3

void PulseInterrupt(void) {
  now = timer0_millis;
  t = now - prev;
  prev = now;

void loop() {

77  Using Arduino / Programming Questions / Re: Arduino as a chronometer ? Know what you are doing ! on: March 01, 2011, 03:59:50 pm
If it makes you feel safer, you can replace MyMicros() with:


//returns current microsecond [us] count
unsigned long MyMicros(void) {
  unsigned long m;
  uint8_t oldSREG = SREG, t;

  m = my_timer0_millis;
  t = TCNT0;
  if ((TIFR0 & _BV(TOV0)) && (t < 249))
  SREG = oldSREG;
  return ((m*250) + t)*4);

for testing purposes, the previous code will work fine. Also, I think it will only run on a 168/328 based arduino running at 16MHz too.
78  Using Arduino / Programming Questions / Re: Arduino as a chronometer ? Know what you are doing ! on: March 01, 2011, 03:47:01 pm
Here's a test for you. Insert the following code, which replaces the TIMER0 ISR, and recheck your results. The arduino TIMER0 ticks off at a 1.024 ms (vs. an implied 1ms) which creates some nasty timer/math issues. Admittedly, this code will break millis(), micros() and some PWM stuff too, but disregard that for now ;-)

Just call MyMicros() instead of micros().


//millisecond counter
volatile unsigned long my_timer0_millis;

  //incremented every 1ms

//returns current microsecond [us] count
unsigned long MyMicros(void) {
  unsigned long m;
  uint8_t t;

  m = my_timer0_millis;
  t = TCNT0;
  if ((TIFR0 & _BV(TOV0)) && (t < 249))
  return ((m*250) + t)*4);

void setup(void) {

  //turn off interrupts
  //replace arduino timer0 code with our timer
  my_timer0_millis = 0;
  // 16Mhz/64 prescale/250 counts = 16000000/64/250 = 1000us (1ms)
  TCCR0A = 0;
  TCCR0A |= (1<<WGM01);            // CTC mode, top=OCR0A, TOV0 set @ max, update immediate
  TCCR0B = 0;
  TCCR0B |= (1<<CS01) | (1<<CS00); // F_CPU/64
  TIMSK0 |= (1<<OCIE0A);           // enable CTC A interrupt
  OCR0A = 249;                     // 249 results in a 250 count rollover




79  Forum 2005-2010 (read only) / Development / Re: ATTiny85 port (work in progress) on: June 05, 2010, 09:34:33 am
attiny85 + avrstudio + avrdude = much less pain.
80  Forum 2005-2010 (read only) / Interfacing / Re: millis (crystal) accuracy & thoughts on: December 25, 2010, 01:09:52 pm
Well researched mspguy, I assumed the millis actually meant millis.

So one may wonder why they didn't /250 by using an output compare interrupt? Or is that used for PWM?


precisely what they did in the Aiko Framework for arduino:
81  Forum 2005-2010 (read only) / Interfacing / Re: millis (crystal) accuracy & thoughts on: December 25, 2010, 01:00:50 pm
If you examine the millis code you will find out this:
82  Forum 2005-2010 (read only) / Interfacing / Re: millis (crystal) accuracy & thoughts on: December 24, 2010, 08:27:38 pm
Running a 7-segment display directly with the following code solved my timing issues.

//7 segment timer test
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000
#include <avr/delay.h>

// SBI and CBI to set bits
#define sbi(port_name, pin_number)   (port_name |= 1<<pin_number)
#define cbi(port_name, pin_number)   ((port_name) &= (uint8_t)~(1 << pin_number))

int d[10];
//wiring millis value
extern volatile unsigned long timer0_millis;

void setup() {
  /* 7-segment pin alignment
   LCD - Arduino
    1  -  A0
    2  -  A1
    6  -  A2
    8  -  A3
    13 -  D0
    15 -  D1
    12 -  D2
    3  -  D3
    5  -  D4
    10 -  D5
    14 -  D6
  DDRC = DDRC | 0b0111111;      // Set data direction for port C (DIG1,...DP)
  PORTC = PORTC | 0b0011111;      // Initialize all digits off
  DDRD = DDRD | 0b11111110;      // Set data direction for port D (A,B,...,G)
  PORTD = PORTD | 0b00000000;      // Initialize all digits off

void loop() {
  // Main loop: update display
  int i;
  while(1) {
    for (i=0; i<4; i++) {
      //total time per loop ~5.5ms@16MHz
      display(d[5 - i], i);
      //this delay controls individual segment on-time/brightness, longer = brighter
      //clear display
      PORTC = PORTC | 0b0011111;;
      PORTD = 0;
    //this delay controls all segments off-time/brightness, shorter = brighter

void ExtractDigits(unsigned long num) {
  int i;
  i = 0;
  while(num > 0) {
    d[i++] = (int)num%10;
    num /= 10;

// Output number to digit 0,1,2, or 3, 4 to display dots
void display(int number, int digit) {
  cbi(PORTC, digit);      // Turn on corresponding digit
  switch(number) {      // Set PORTD, display pins, to correct output
    case 0:
      PORTD = 0b01111110;
    case 1:
      PORTD = 0b00001100;
    case 2:
      PORTD = 0b10110110;
    case 3:
      PORTD = 0b10011110;
    case 4:
      PORTD = 0b11001100;
    case 5:
      PORTD = 0b11011010;
    case 6:
      PORTD = 0b11111010;
    case 7:
      PORTD = 0b00001110;
    case 8:
      PORTD = 0b11111110;
    case 9:
      PORTD = 0b11011110;
      PORTD = 0b01111110;  //0

I think I found the issue. It appears to be in the sparkfun serial 7-segment display. The problem is outlined here:

thanks for everyone's help.
83  Forum 2005-2010 (read only) / Interfacing / Re: millis (crystal) accuracy & thoughts on: December 20, 2010, 11:59:45 am
Thanks for all of the responses so far.

Is this a start-time-stop application?
How many things are being timed?
Do you need to display the time while the timer is running?
How long is the event being timed?
What accuracy do you need?

I am making a split timer, where the timer will run continuously with intervals tripped by an electronic switch.

One individual is timed over several intervals. The overall event could be from 15 minutes to several hours, with the splits lasting in the range of 1-10 minutes long.

I need to display the interval times.

I want at least a tenth-of-second accuracy, hundredths would be better.

Man, it looks like I was having a conversation with myself?
84  Forum 2005-2010 (read only) / Interfacing / Re: millis (crystal) accuracy & thoughts on: December 19, 2010, 05:58:20 pm
I can tell you that here in the future, we expect proper data, just as they did back in 2010 (and 1910 and 1810, etc.)
Proper data has an explanation for each line. Does your list represent readings at 1min, 2min, etc?  Then say so. Even back in 2010, not doing so was called "unlabeled".
Proper data is concise. It does not include the same number represented as seconds and milliseconds. Even back in 2010 repeating values was called "redundant".

Your responses have become redundantly useless.

I'll try the same test with an LCD hooked up via parallel (eliminating spi) and report back.

I promise to post concise labeled unredundant proper data in the future.
85  Forum 2005-2010 (read only) / Interfacing / Re: millis (crystal) accuracy & thoughts on: December 19, 2010, 04:46:02 pm
Being from the future, I assumed you wouldn't need me to explain all this.  smiley-wink

A photo was taken of the arduino & stopwatch at approximately 1-minute intervals for 10 minutes. The columns represent the time difference between the 2 clocks. The difference between the clocks at the start had the arduino 1.11 seconds behind the stopwatch.  After approx. 10-minutes, the arduino was 0.27 seconds ahead. I hope that explains the data.

I repeated the experiment using 3 different arduinos and several stopwatches with similar results.

It doesn't seem to make any sence to me either.
86  Forum 2005-2010 (read only) / Interfacing / Re: millis (crystal) accuracy & thoughts on: December 19, 2010, 04:01:03 pm
see reply #9.
87  Forum 2005-2010 (read only) / Interfacing / Re: millis (crystal) accuracy & thoughts on: December 19, 2010, 03:07:18 pm
Lets be realistic here.
As has already been observed, if we are talking about an application like casual timing for track and field (i.e. not official competition like Olympics, etc.) the crystal in your typical microcontroller (like Arduino) is probably sufficient. Your human error in hitting start/stop is greater than the error from a typical microprocessor crystal over 10 minutes.

I think you ignored looking at my data, because I'm seeing unacceptable timing errors for anything more accurate than an egg timer.  smiley-wink

Thanks for the RTC recommendations.

I'll try hooking up an lcd via parallel.
88  Forum 2005-2010 (read only) / Interfacing / Re: millis (crystal) accuracy & thoughts on: December 19, 2010, 12:33:00 pm
And try to use hand stopwatches over a few seconds is just crazy

1. human reaction time on stopwatch (try starting and stopping two stop clocks at the same time in each hand)
2. delay from pressing stop on arduino till it writes it to serial to display
3. same for pressing start (the arduino must process some code)

The above timer comparison was accomplished with no human input. I simply started both an arduino (with code posted above) and a stopwatch, placed them side-by-side, and took photos of them at approximately 1-minute intervals over a period of 10-minutes. I repeated this with several different types/models of stopwatches, all with similar results.

The results posted above are the differential between both timers.

Wildly inaccurate.

No pressing of buttons.
89  Forum 2005-2010 (read only) / Interfacing / millis (crystal) accuracy & thoughts on: December 27, 2009, 04:08:41 pm
I'm trying to make a sports timer with an Arduino and I'm finding the crystals appear to be wildly inaccurate. Comparing photos of the (3 different) Arduino vs. (several) handheld stopwatches, I get results like this over a period of 10 minutes:

Delta-s      delta-ms
-1.11       -1110
-1.22       -1220
-1.36       -1360
-1.21       -1210
-1.03       -1030
-0.48       -480
-0.31       -310
-0.72       -720
-0.06       -60
0.09        90
0.27        270

The timer code on the Arduino is simply reading millis() and displaying via SPI interface to a Sparkfun 4-digit 7-segment display. Relevant code below:

//declare globals
volatile unsigned long current_time, *display_time;

void SpiTransfer(volatile char data) {
  SPDR = data;                    // start the transmission
  while (!(SPSR & (1<<SPIF)));    // wait for the end

void DisplayTime(void) {
  PORTB &= ~(1<<PORTB2);                   //set SPI_SS low
  SpiTransfer( (*display_time/600)%10 );   // thousands digit
  SpiTransfer( (*display_time/100)%6 );    // hundreds digit
  SpiTransfer( (*display_time/10)%10 );    // tens digit
  SpiTransfer( *display_time%10 );         // ones digit
  PORTB |= (1<<PORTB2);                    //set SPI_SS high

void setup(void) {
  uint8_t junk;

  //setup spi in order to talk to 4-digit 7-segment display_time
  pinMode(SPI_MISO, INPUT);
  pinMode(SPI_MOSI, OUTPUT);
  pinMode(SPI_SS, OUTPUT);
  digitalWrite(SPI_SS, HIGH);
  //spi enabled, msb 1st, master, clk low when idle,
  //sample on leading edge of clk, system clock/64
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);
  junk = SPSR;
  junk = SPDR;

  //display ticking timer.
  display_time = &current_time;
  current_time = 0;

  //offset between now and system time
  millis_offset = millis();

void loop(void) {
  //main loop
  while(1) {
    //update display
    current_time = (millis() - millis_offset)/100;

I've tried using nonblocking delays to slow the calls to millis(), thinking that was the culprit, but I get similar results. Does the SPI call block the millis() timer interrupt?

I'm thinking of using a DS3231 (like a chronodot) to create an accurate 1Hz interrupt on the Arduino. Any thoughts? I'm open to ideas.

90  Forum 2005-2010 (read only) / Interfacing / Re: How do I interface a 5v & 3.3v arduino on: March 29, 2010, 02:05:33 pm
thanks, that sure seems easier, so I'm experimenting with the voltage divider now.
Pages: 1 ... 4 5 [6] 7