Hello! I am working on a project for my university that involves an atmega 32U4 interfaced to a raspberry pi via a PCB. I am utterly useless pretty bad when it comes to MCU registers and that level of programming, though I am learning quite a lot, ive been trying to understand this for weeks now and I just don't know how to approach it. I want help with which pins/ports to connect on my PCB, and ill learn the code as I go once it is together. Unfortunately, shipping is so expensive that I wont get another shot at the PCB, and I really don't want to bodge it as this project is supposed to serve students for years to come and has to be reliable. I have summarized 5 questions that might help me get there and choose the pins, but if more detail is needed, I added more details below the questions in quotes.
Can I have both 25 kHz PWM outputs on one timer? I think I should, as far as I understand, changing prescaler to 8x is timer wide
In the 32U4 datasheet, all the "output compare" alternate functions are written as "OC0A" or "OC1B", but then there are ones with a dot, like "OC.3A" or "OC.4D". Do the dots have any significance?
Which timer should I use for the fans PWM mentioned in Q1? I know to avoid timer 0 as it has millis(), but also just one output, so what timer do you suggest I get two 25 kHz outputs from
Does my 15-100 Hz fans tachometer warrant connecting two of them to the T0 and T1 pins (PD7 and PD6), leaving a fan out? Or can I just connect all three to any digital pin and figure something out? I guess Pin change interrupt wont be the best here because two pins might possibly pulse at the same time (maybe one will pulse while the other's interrupt is going)
Are all pins equally as "fast" for bit banging the neopixels? Should I just use the nearest pin to the connector (excluding the analog port maybe?)
This is a project that will sit in the university library, made to work for a years for student use for borrowing and returning books via an RFID reader, which also guards the entrance from theft. This specific PCB will sit on a Raspberry pi to handle peripherals. I am designing this PCB on my own as a learning exercise, but unfortunately I have ran into a roadblock which no one I know was able to help in.
The 32U4 talks to the raspberry pi via USB, and will be programmed via Arduino IDE to function like an Arduino Leonardo (with a custom VID and PID). The 32U4 will have to do the following:
2 general Digital out: One to enable a constant current LED driver that is 10 meters away, the other to send a pulse to a mosfet to open the enclosure door
3 general Digital in (1 interrupt): 1 overheat fault line for LED driver, one door switch, and a failsafe interrupt pin from the raspberry pi just in case serial goes out, to maintain alarm function (interrupt will just set a flag, nothing long)
I2C for ambient sensors
Serial over USB, which is how the PI and the 32U4 will talk. Why use a level shifter when USB is there?
the 2/3 fan in, 2 fan out, and 2 neopixel out pins. The question is about these, so more detail is below
The more relevant parts are the following, also in a quote because this question is way too long
Reading the tachometer of 3 fans (not interested in precisely monitoring RPM, just making sure it is spinning faster than 15 Hz (400 RPM), and up to 100 Hz)
2 25 kHz PWM fan outputs, does not have to be high resolution, an 8x prescaler with 79 counts will give me the needed 25kHz, with a duty cycle resolution of 1.25%.
Two neopixel strings, probably driven via bitbang and manual timing, because of the way I want to set them up this seemed to be better than using the adafruit library, and fastLED doesnt support RGBW
I tried my best at doing my own research. I asked around, I read the registers part of the datasheet which started off as gibberish and ended up reading just like when you try to read a book in a dream... It just doesn't work.
Can I have both 25 kHz PWM outputs on one timer? I think I should, as far as I understand, changing prescaler to 8x is timer wide
Yes, it's possible to have both 25kHz PWM outputs on one timer, in the case of the Arduino Leonardo timer 1 on digital pins 9 and 10:
void setup()
{
pinMode(9, OUTPUT); // Set digital pin 9 to an OUTPUT
pinMode(10, OUTPUT); // Set digital pin 10 to an OUTPUT
pinMode(11, OUTPUT); // Set digital pin 11 to an OUTPUT
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1); // Enable the PWM outputs OC1A, OC1B and OC1B on digital pins 9, 10 and 11
TCCR1B = _BV(WGM13) | _BV(CS10); // Set phase and frequency correct PWM and prescaler of 1 on timer 1
ICR1 = 319; // Set TOP value for phase and frequency correct PWM on timer 1 for 25kHz
OCR1A = 80; // Set OCR1A to output 25% on digital pin 9
OCR1B = 160; // Set OCR1B to output 50% on digital pin 10
OCR1C = 240; // Set OCR1C to output 75% on digital pin 11
}
void loop() {}
I've added a third 25kHz PWM output on D11 for good measure. This code sets up the outputs for phase and frequency correct (dual slope/center aligned) PWM.
In the 32U4 datasheet, all the "output compare" alternate functions are written as "OC0A" or "OC1B", but then there are ones with a dot, like "OC.3A" or "OC.4D". Do the dots have any significance?
No, it's probably a typo. in the datasheet.
Which timer should I use for the fans PWM mentioned in Q1? I know to avoid timer 0 as it has millis(), but also just one output, so what timer do you suggest I get two 25 kHz outputs from
Probably best to use timer 1, as it has a total of 3 outputs.
Does my 15-100 Hz fans tachometer warrant connecting two of them to the T0 and T1 pins (PD7 and PD6), leaving a fan out? Or can I just connect all three to any digital pin and figure something out? I guess Pin change interrupt wont be the best here because two pins might possibly pulse at the same time (maybe one will pulse while the other's interrupt is going)
If you had a single tachometer input then you could use timer 3's Input Capture Unit on the microcontroller's ICP3 pin. However as you have two inputs, it might be easier just to use interrupts or pin change interrupts together with the millis() or micros() functions, to measure the time difference between rising and/or falling eges. 15Hz to 100Hz interrupts aren't too onerous for an Atmega32U4.
Yes, it's possible to have both 25kHz PWM outputs on one timer, in the case of the Arduino Leonardo timer 1 on digital pins 9 and 10:
void setup()
{
pinMode(9, OUTPUT); // Set digital pin 9 to an OUTPUT
pinMode(10, OUTPUT); // Set digital pin 10 to an OUTPUT
pinMode(11, OUTPUT); // Set digital pin 11 to an OUTPUT
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1); // Enable the PWM outputs OC1A, OC1B and OC1B on digital pins 9, 10 and 11
TCCR1B = _BV(WGM13) | _BV(CS10); // Set phase and frequency correct PWM and prescaler of 1 on timer 1
ICR1 = 319; // Set TOP value for phase and frequency correct PWM on timer 1 for 25kHz
OCR1A = 80; // Set OCR1A to output 25% on digital pin 9
OCR1B = 160; // Set OCR1B to output 50% on digital pin 10
OCR1C = 240; // Set OCR1C to output 75% on digital pin 11
}
void loop() {}
Oh my god! Thank you, I've seen a lot of code, but your comments made it click!
Your code sets phase correct PWM which counts up and down, so acts like a 2x prescale, and you clear the registers at 319 which is 640 counts. It stays high till it gets to top (say 158, so 320 counts). this works because timer 1 is 16 bits
ICR1 and ICR3 are used for timers 1 and 3, as you said, 3 doesnt have enough outputs, and 0 is used by millis, but just so im sure, another option is timer 4 which has the two outputs I need, but doesnt have something like ICR4. Instead, it uses OCR4C. It also supports phase correct mode as far as ive understood.
So is there a reason to go with one or the other, or did you suggest timer 1 just out of familiarity?
I thought it would be better to have another reply instead of editing, as 20 minutes have passed and maybe someone read the above and is replying as I type
So is there a reason to go with one or the other, or did you suggest timer 1 just out of familiarity?
Actually, I just looked at register on page 173 of the datasheet, OCR4C is written as an 8 bit register, if I want to use it as 10 bits I need to do more operations. So yes to get a duty cycle resolution of 1/320 easily, I need to use the 16 bit timer 1. However, I dont have a high resolution requirement, so Timer 4 with phase correct PWM, a prescaler of 2, and a TOP (OCR4C) value of 159, which still is a resolution of 1/160 which is more than good enough.
So other than a 16 bit timer giving me better resolution, which I do not need for a fan anyway, is there anything else to consider when thinking of which to use? Especially arduino-wise, if it is used for any functions for example, or maybe if some library uses either
Timer 4 seems less likely to be used as there isnt something like it on the 328, but if there isnt any such requirement ill just use whichever pins are nearer
So other than a 16 bit timer giving me better resolution, which I do not need for a fan anyway, is there anything else to consider when thinking of which to use?
Not really, other than the fact that it's 8-bits, it will act in the same way.
In comparison with the Atmega328P, the Atmega32U4 has an additonal 16-bit timer 3 and a 10-bit high speed timer 4, however it lacks the 328P's 8-bit timer 2.