I have been given a task to generate 4 square waves with different frequencies which should be less than 30hz using arduino mega 2560.I have been through many posts and am little bit confused using OCR. Please guide me through this.
For frequencies below 30Hz, you can simply do this in software, you don't need to directly use any of the ATmega's hardware timers. Just use the millis() function.
Sorry I did't get you as I am new to Arduino. Can you please explain me with an example code?
Example code in the IDE under the blink without delay file name.
File menu -> Examples
That blinks one LED, just extend it to three.
am little bit confused using OCR
What has optical character recognition got to do with your problem?
Grumpy_Mike:
What has optical character recognition got to do with your problem?
I think they meant Output Compare Register. But that also has little to do with frequency (more a Duty Cycle thing).
If the OP wanted to use one timer per frequency they would use one of the Waveforms Generator Modes and use a combination of 'prescale' and 'TOP' to set the frequency.
Using milliseconds in the 30Hz range would only give about 3% precision. I would go with the microsecond timer for better frequency precision.
You could consider using a DDS function - for a square wave, the ADC is unnecessary.
I have been given a task .....
Is this a homework question?
This code compiles. It might even work.
const byte ChannelCount = 4;
// Output pin numbers for the oscillators
const byte Pins[ChannelCount] = {2, 3, 4, 5};
const uint16_t PINRegs[ChannelCount] =
{
port_to_input_PGM[digital_pin_to_port_PGM[Pins[0]]],
port_to_input_PGM[digital_pin_to_port_PGM[Pins[1]]],
port_to_input_PGM[digital_pin_to_port_PGM[Pins[2]]],
port_to_input_PGM[digital_pin_to_port_PGM[Pins[3]]]
};
const byte PinMasks[ChannelCount] =
{
digital_pin_to_bit_mask_PGM[Pins[0]],
digital_pin_to_bit_mask_PGM[Pins[1]],
digital_pin_to_bit_mask_PGM[Pins[2]],
digital_pin_to_bit_mask_PGM[Pins[3]]
};
// Frequencies in Hz
const float Frequencies[ChannelCount] = {30.0, 29.3, 27.6, 25.2};
// Hale-wave intervals in microseconds
const unsigned long Intervals[ChannelCount] =
{
(1000000UL / 2) / Frequencies[0],
(1000000UL / 2) / Frequencies[1],
(1000000UL / 2) / Frequencies[2],
(1000000UL / 2) / Frequencies[3]
};
// Timers
unsigned long Timers[ChannelCount];
void setup()
{
for (byte i = 0; i < ChannelCount; i++)
{
pinMode(Pins[i], OUTPUT);
}
}
void loop()
{
for (byte i = 0; i < ChannelCount; i++)
{
if (micros() - Timers[i] >= Intervals[i])
{
Timers[i] += Intervals[i];
*((byte *) PINRegs[i]) = PinMasks[i]; // Write a 1 to a bit in the PIN register to toggle the pin
}
}
}