Hot answers tagged

16

The other answers are very good, but I want to elaborate on how micros() works. It always reads the current hardware timer (possibly TCNT0) which is constantly being updated by the hardware (in fact, every 4 µs because of the prescaler of 64). It then adds in the Timer 0 overflow count, which is updated by a timer overflow interrupt (multiplied by 256). ...


14

Background The function millis () returns an unsigned long, which is the number of milliseconds since the processor was reset (until it overflows). See: http://arduino.cc/en/Reference/Millis Example: unsigned long startTime = millis (); Since there are 232 bits in an unsigned long it can count from 0 to 4294967295. Computing this in terms of days we ...


13

This isn't weird looking. It's what normal MCU code actually looks like. What you have here is an example of the concept of memory-mapped peripherals. Basically, the MCU hardware has special locations in the SRAM address space of the MCU assigned to it. If you write to these addresses, the bits of the byte written to address n control the behaviour of ...


10

The real time clock method is the most accurate way but otherwise use millis unsigned long startMillis = millis(); while (millis() - startMillis < LONG_DELAY_MS); This will delay up to approx. 4294967295ms (2^32-1) or 49 days, after which the timer will catch up to the value of startMillis


10

It is indeed possible to generate a 56 kHz signal with an Arduino timer. A timer actually can be seen as a special register, in the MCU, that holds a value (starting at 0) that gets incremented at a frequency that is the MCU clock frequency (16 MHz on Arduino Uno), possibility divided by a factor called prescaler. When that value reaches a limit, ...


9

volatile only informs the compiler's code generator that the variable may be modified by something other than the code being generated, so not to assume any copy of it remains accurate. ISR code must be written/generated under the assumption that it has no context at entry, and preserve the CPU's context around its (ISR's) own operation. So, as with the ...


9

A DateTime is a full class with lots of methods to it - a time_t is just an unsigned long. time_t is used to store the number of seconds since the epoch (normally 01/01/1970) The Arduino Time library returns a time_t to the now() function - but RTCLib return s a DateTime object. The DateTime object, though, has a unixtime() method which will return a ...


9

The Arduino core does things at startup. One of those things is to configure the timers ready for PWM operation. Here's the relevant bits from init() in wiring.c: // set timer 1 prescale factor to 64 sbi(TCCR1B, CS11); #if F_CPU >= 8000000L sbi(TCCR1B, CS10); #endif #if defined(TCCR1A) && defined(WGM10) sbi(TCCR1A, WGM10); #...


8

First I'll tackle what TCCR0B=TCCR0B&0b11111000|0x01; means from a pure programming perspective: Let's break it down into parts: TCCR0B = TCCR0B & 0b11111000 | 0x01; TCCR0B is a register. It could be any variable really - it's just "a value" in this context. Just because it happens to control one of the timers is besides the point. 0b11111000 ...


8

It is not wrong to use millis() or micros() within an interrupt routine. It is wrong to use them incorrectly. The main thing here is that while you are in an interrupt routine "the clock isn't ticking". millis() and micros() won't change (well, micros() will initially, but once it goes past that magic millisecond point where a millisecond tick is required ...


8

One microsecond is only 16 CPU cycles. The CPU needs 4 cycles to prepare itself for servicing the interrupt (save the program counter, load the interrupt vector and clear the I bit in SREG). The interrupt vector itself is a jmp instruction that takes 2 cycles. When the ISR is done, it executes the reti instruction (return from interrupt) that takes 4 cycles....


7

You don't seem to use standard Arduino stuff since you defined your own main() which is normally avoided when programming Arduino. If you take a look at Arduino provided main() (in hardware/cores/arduino/main.cpp), you'll see how it is defined: #include <Arduino.h> int main(void) { init(); #if defined(USBCON) USBDevice.attach(); #endif ...


7

delay() has its uses, but for long delays it's no good. It simply tells the microcontroller to do nothing for x clock cycles. During that time, your Arduino can't do anything else. Your best bet would be to use a thing called a Real Time Clock (RTC). These chips are specifically made to keep track of time, and you can connect them to your Arduino with ease. ...


7

You need to define the parameters of the problem more clearly. First, and most importantly, what is the shutterspeed you'll be using? If it's longer than 1 ms, then you can't use a 7-segment display to show the MS count, since the camera shutter would be open for multiple values. Even if your shutterspeed is a single MS, your shutter won't be ...


7

You could use the watchdog interrupt and have your MCU sleep while waiting and save power. But notice that you'll only save power if your board also saves it. That means you have to have a low quiescent voltage regulator instead of the usual regulators that equip the most common Arduino boards, such as the Uno. Otherwise, it doesn't matter whether your MCU ...


7

The Arduino main() calls loop() continuously, in a tight loop. Thus your AllTimer::setTimer() is called continuously, and each time it resets the counter (TCNT1 = 0x0000;). Thus the counter can never overflow.


6

Have a look at the code for attachInterrupt() and detachInterrupt() in /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/WInterrupts.c (well, that's where they are on a Mac, anyway. Arduino file structure on other OSes' probably looks similar in the lower levels of the path). It appears that attachInterrupt() assumes that the ...


6

They do not conflict as millis() strictly reads the immediate value in TCNT0 whereas PWM via timer 0 uses the hardware's ability to compare the value of TCNT0 with the values in OCR0x without affecting the value of any of them.


6

I cannot find any information about the arduino micro. I also don't know exactly what the proper keywords are that i need to find the relation between timers and pins. Go to the products page for the Micro on the Arduino web site. You will find that the processor is the ATmega32U4. Download the datasheet for the ATmega32U4 - it's on that page. Download the ...


6

Set the timer for every hour, which is within the limit. In your action, keep a static int, initialized to zero, which you increment each time. When it ==12, do the thing you want to do and reset your int back to zero.


6

As explained in the previous answers, your actual problem is not the accuracy of delayMicroseconds(), but rather the resolution of micros(). However, to answer your actual question, there is a more accurate alternative to delayMicroseconds(): the function _delay_us() from the AVR-libc is cycle-accurate and, for example _delay_us(1.125); does exactly what ...


5

Turns out the problem was that timer 0 and 2 on the arduino uno are 8 bit. Set a different prescaler and I'm golden // set up Timer 2 TCCR2A = 0; // normal mode TCCR2B = 0; // TCCR2A = bit(WGM21) | bit(CS21); // CTC, scale to clock / 8 TCCR2A = (1 << WGM21); //Enables CTC for timer TCCR2B |= (1 << CS21); TCCR2B |= (...


5

Just to add to @Ignacio's answer which has directly answered your question. The "conflict" you speak of is in relation to Timer0's prescaler. For the most part, you can use those pins (incidentally pins 5 and 6 on the UNO) with PWM without an issue, and read the correct value of millis() (as well as get the expected delay from delay) Where you run into ...


5

In CTC mode the top is OCR3A, not OCR3B! After that TIMSK3 |= (1 << OCIE3B); should also be changed to TIMSK3 |= (1 << OCIE3A);, and ISR(TIMER3_COMPB_vect) to ISR(TIMER3_COMPA_vect) For 3Hz, OCR3A should be 5208, not 20. Technically TCCR3B |= (1 << WGM12); should be TCCR3B |= (1 << WGM32);


5

Try putting sei(); at the start of the ISR. I think I2C needs interrupts enabled to work.


5

I2C requires interrupts to work, however enabling interrupts inside an ISR is not recommended. For one thing you may get into a race condition, where another interrupt occurs while processing the existing one. Since you are doing virtually nothing in your main loop, a more sensible design would be to simply test if it is time to take a reading, and when ...


5

Fixing the timekeeping functions with your PWM settings is not so simple. You should at least try to rewrite ISR(TIMER0_OVF_vect), micros(), and probably delay(). Here is why: First, there is a rounding problem. Time is kept using two global variables: volatile unsigned long timer0_millis; static unsigned char timer0_fract; The first one is what millis() ...


5

One approach would be use of a DS3231 (Precision Real Time Clock) module. Such modules sell on Ebay for under $1. Search for ds3231 arduino. Typically, these modules have a six-pin connector, with pins labeled 32K, SQW, SCL, SDA, VCC, and GND. As noted in DS3231 specs, the INT/SQW pin is used either for square-wave output or for interrupt output. On ...


5

I'm running into an issue because it takes milliseconds as an int ... No it doesn't. Look at the function prototype: int setInterval(long d, timer_callback f); Call function f every d milliseconds. The callback function must be declared as void f(). The interval d is a long. The int you see is the return value from the function, not the interval.


5

The default configuration of these chips, as they come from the factory, is to use their internal 8 MHz RC oscillator downscaled at 1 MHz. So you do not need any extra oscillator to program them. Once you program the chip the first time, if you configure it to use an external resonator/oscillator, then you do need to have that attached in order to reprogram ...


Only top voted, non community-wiki answers of a minimum length are eligible