Hello,
I am writing a programme that communicates over I2C with a raspberry pi. The raspberry pi sends values for the Arduino to set the PWM duty cycles on pins 3, 9, 10 and 11. I have alread changed the PWM frequency on these pins to ~ 30 Hz to match it with the system which I am controlling. This is done using:
TCCR1B = TCCR1B & 0b11111000 | 0x05;
TCCR2B = TCCR2B & 0b11111000 | 0x07;
Currently I can set PWM duty cycles between 0 - 255 (8-bit). I have been reading that it is possible (hardware can is sufficient) to set atleast some of these pins to have a better duty cycle resolution (10-bit; 0 - 1024). Is this possible with the Uno? If so could you give me some pointers to how I should go about it. I am concerned that since I have changed the PWM frequency that this will intefere with my ability to adjust the duty cycle resolution since they're intricately related?
Cheers,
Andy
Here is my code:
#include <Wire.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/wdt.h>
#define SLAVE_ADDRESS 0x03 // I2C Address of the Arduino
int howMany = 0, debug = 0;
int state = 0,x,y,z;
char buffer100[7];
int position=0,A,B;
char str,values[100],warr[20];
String receivedMessage,X,Y,Z;
int startStringPosition,startStringPosition1,startStringPosition2;
int endStringPosition,endStringPosition1,endStringPosition2;
void setup() {
pinMode(13, OUTPUT);
Serial.begin(115200); // start serial for output
Wire.begin(SLAVE_ADDRESS); // initialize i2c as slave
TCCR1B = TCCR1B & 0b11111000 | 0x05; // Reduce PWM Frequency to 30 Hz.
TCCR2B = TCCR2B & 0b11111000 | 0x07; // Reduce PWM Frequency to 30 Hz.
// define callbacks for i2c communication
Wire.onReceive(receiveEvent);
Serial.println("Listening on Serial Port");
wdt_enable(WDTO_8S); // Setting watchdog timer for 8s. If no reset of timer within 8s, Arduino will reset.
}
void loop() {
delay(100);
}
// callback for received data
void receiveEvent(int howMany)
{
position = 0;
digitalWrite(13,HIGH); // When data recieved, set LED on PIN13 high.
while(Wire.available()) //Reading data over I2C.
{
str = Wire.read();
values[position] = str;
position++;
}
values[position] ='\n';
// -------------- Extracting values for PWM Duty Cycles from String.
// -------------- String format: A%dB%dC%dZ.
receivedMessage = String(values);
startStringPosition= receivedMessage.indexOf('A')+1;
endStringPosition= receivedMessage.lastIndexOf('B');
X=receivedMessage.substring(startStringPosition,endStringPosition);
if(debug > 0){ // Show X if in Debug mode. This slows program down.
Serial.print(X);
}
char Xchar[X.length() +1];
X.toCharArray(Xchar,sizeof(Xchar));
x=atoi(Xchar);
startStringPosition1= receivedMessage.indexOf('B')+1;
endStringPosition1= receivedMessage.lastIndexOf('C');
Y=receivedMessage.substring(startStringPosition1,endStringPosition1);
if(debug > 0){
Serial.print(Y);
}
char Ychar[Y.length() +1];
Y.toCharArray(Ychar,sizeof(Ychar));
y=atoi(Ychar);
startStringPosition2= receivedMessage.indexOf('C')+1;
endStringPosition2= receivedMessage.lastIndexOf('Z');
Z=receivedMessage.substring(startStringPosition2,endStringPosition2);
if(debug > 0){
Serial.print(Z);
}
char Zchar[Z.length() +1];
Z.toCharArray(Zchar,sizeof(Zchar));
z=atoi(Zchar);
// --- Using values to set PWM Values (0 - 255)
// analogWrite(3,y); // Not used Currently
analogWrite(9,x);
analogWrite(10,y);
analogWrite(11,z);
digitalWrite(13,LOW); // Resetting the LED on PIN13
wdt_reset(); // Reseting watchdog timer.
}