I'm using the arduino to generate a 100kHz pwd using timer 1
void setup() {
// put your setup code here, to run once:
// Timer 1 Fast PWM mode *toggling* OC1A at 50kHz with *two* OCR1A counts
// And 7.32 bits 0-159 PWM on OC1B at 100kHz
// Output on OC1B
// Set at TOP, Clear at OCR1B
// WGM =15 0b1111
DDRB |= bit(DDB1) | bit(DDB2); // atmega168/UNO OC1A and OC1B (Tested by OP/Luis)
TCCR1A = bit(WGM11) | bit(WGM10) | bit(COM1A0) | bit(COM1B1) ; // Toggle OC1A, Clear on OC1B
TCCR1B = bit(WGM13) | bit(WGM12) | bit(CS10); // Set /1 prescaler
OCR1A = 159 ;//79; // Set TOP count to 16000000/(2*PreScaler*Ftoggle)
// or 16000000/(PreScaler *Ftimer)
OCR1B = 10; // 10/160 duty cycle
TCNT1 = 0 ;
}
void loop() {
// put your main code here, to run repeatedly:
OCR1B = 160/4 -1 ; // 25% duty cycle.
}
I used this to test the modules:
Receiver
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int LED1 = 3;
void setup(void){
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(1,pipe);
radio.startListening();
pinMode(LED1, OUTPUT);}
void loop(void){
if (radio.available()){
bool done = false;
while (!done){
done = radio.read(msg, 1);
Serial.println(msg[0]);
if (msg[0] == 111){delay(10);digitalWrite(LED1, HIGH);}
else {digitalWrite(LED1, LOW);}
delay(100);}}
else{Serial.println("No radio available");}}
Transmitter
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int SW1 = 7;
void setup(void){
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(pipe);}
void loop(void){
if (digitalRead(SW1) == HIGH){
msg[0] = 111;
radio.write(msg, 1);}}
I'm using this library https://github.com/TMRh20/RF24
And it works ok, now first issue is that both, RF24 and the pwm are using the pin 10 but the library allows you to change it, so now I'm using pin 7 instead. I tested it again and still works fine.
But when I add the lines at the setup to use the pwd the communication doesn't work
DDRB |= bit(DDB1) | bit(DDB2); // atmega168/UNO OC1A
TCCR1A = bit(WGM11) | bit(WGM10) | bit(COM1A0) | bit(COM1B1) ; // Toggle OC1A, Clear on OC1B
TCCR1B = bit(WGM13) | bit(WGM12) | bit(CS10); // Set /1 prescaler
OCR1A = 159 ;//79; // Set TOP count to 16000000/(2*PreScaler*Ftoggle)
// or 16000000/(PreScaler *Ftimer)
OCR1B = 10; // 10/160 duty cycle
TCNT1 = 0 ;
I try line by line and the issue is here:
TCCR1B = bit(WGM13) | bit(WGM12) | bit(CS10); // Set /1 prescaler
When setting the prescaler at 1.
Which is the dependency of the RF24 on this timer? and which options to I have to make it work
EDIT.
Now I'm using pins 6 and 7 for CE and CS Also removed "| bit(COM1A0) " form the register setting
Still doesn't work
I've this
void setup(void)
{
/// RF settings
Serial.begin(9600);
radio.begin();
//radio.openReadingPipe(1,pipe);
//radio.startListening();
pinMode(LED1, OUTPUT);
/// end RF settings
//// pwd settings
DDRB |= bit(DDB1) | bit(DDB2);
OCR1A = max_count; // 16000000/(PreScaler *Ftimer)
OCR1B = 10;
TCCR1A = bit(WGM11) | bit(WGM10) | bit(COM1B1); // bit(COM1A0) | Toggle OC1A, Clear on OC1B
TCCR1B = bit(WGM13) | bit(WGM12) | bit(CS10); // Set /1 prescaler
TCNT1 = 0 ;
////
}
If I put the settings for the PWM before the settings for the RF24 then the PWM doesn't work, the RF settings at first the the communications doesn't work.
radio.begin() must be overwriting the registers but I haven't found how.
-
1The "TCCR1A = bit(WGM11) | bit(WGM10) | bit(COM1A0) | bit(COM1B1) ; // Toggle OC1A, Clear on OC1B" line set up the PWM to control both the OC1A and OC1B pins, which are 9 and 10 on an Arduino Uno, Is Pin 9 interfering with the RF24 per the "RF24 radio(9,10\7円);" line? If so, you could take out the " | bit(COM1A0)" portion to free up pin 9 for digital IO rather than PWM.Dave X– Dave X03/09/2016 14:02:30Commented Mar 9, 2016 at 14:02
-
1Maybe the fact that you have pin 10 as PWM is messing up the SPI module that requires pin 10 to be set to output for SPI to operate?Majenko– Majenko03/09/2016 16:19:01Commented Mar 9, 2016 at 16:19
-
@DaveX I try it, still doesn't workLuis Ramon Ramirez Rodriguez– Luis Ramon Ramirez Rodriguez03/09/2016 20:48:27Commented Mar 9, 2016 at 20:48
-
@Majenko if the RF24 doesn't need to use pin 10 how can I check if the SPI library is causing the issueLuis Ramon Ramirez Rodriguez– Luis Ramon Ramirez Rodriguez03/09/2016 20:50:16Commented Mar 9, 2016 at 20:50
-
The nRF doesn't need pin 10 but the SPI does. It's a hardware thing. If you can run the pwm without pun 10 it may prove or disprove it.Majenko– Majenko03/09/2016 21:51:12Commented Mar 9, 2016 at 21:51
1 Answer 1
Maybe doing 100kHz PWM with timer2 instead of timer1 would be good. The registers look similar to timer1, but they are only 8 bit, so you can't go bigger than 255 in the compare and count registers. The prescaler would be the same, and the timer controlled pins would be D11 and D3:
//// pwm settings for 100kHz on Timer 2
//// Toggle OC2A/D11/PB3 at 50kHz, PWM OC2B/D3/PD3 at 100kHz:
DDRB |= bit(DDB3); //Enable output
DDRD |= bit(DDD3); //Enable output
// WGM2x=0b111 for fast PWM with TOP=OCR2A
// COM2Ax=0b01 for toggle OC2A at OCR2A
// COM2Bx=0b10 for set@bottom-clear@match_OCR2B PWM
TCCR2A = bit(WGM21) | bit(WGM20)
| bit(COM2B1) // PWM on OC2B
| bit(COM2A0); // Toggle OC2A
TCCR2B = bit(WGM22) | bit(CS20); // Set /1 prescaler
OCR2A = 159; // 16000000/(PreScaler *Ftimer)-1
OCR2B = 10; // 6.25% PWM
TCNT2 = 0 ;
I haven't tested this on an Uno/Atmega328P, but it looks reasonable per the datasheet (p153-157).
If you don't want both the 50kHz toggle and 100kHz PWM outputs, (as in your posted code,) you could disable one or the other and adjust the frequency as needed.