Hello, I am using the Tone() function to create a frequency at 50% duty cycle so it can be read by a campbell scientific datalogger. If I output a tone at 1500Hz, the serial monitor says 1500Hz, but the datalogger reads a frequency of 1485. Similar, I tell it to output at 831, and it outputs as 826Hz. I have swapped arduino Uno's and reloaded the same program with the same results.
I am transferring data from a zigbee to this arduino, but it reads the data fine, it just outputs using tone incorrectly. Below is my code if it might help? The section I output tone at is a little more than halfway down at the
//////////////////////
// Voltage Output //
//////////////////////
part.
Thank you
const int VSensors = 0; // # of voltage 10:1 sensors you will be sending wirelessly for the project.
const int ISensors = 2; // # of ACS711 current sensors you will be sending wirelessly for the project.
const int outputType = 2; // (0,1) 0 = analog voltage output, 1 = PWM output
///////////////
// Libraries //
///////////////
#include <SoftwareSerial.h> // Includes the library softwareSerial which should automatically be included in Arduino 1.6.9 and up
//#include "pitches.h" // Used to test for the command tone() which outputs 50% duty cycle PWM to be detected by CS dataloggers
#define VERSION "1.02" // No idea what this does, but it works
const byte XB_RX = 2; // XBee's RX (Din) pin
const byte XB_TX = 3; // XBee's TX (Dout) pin
const int XBEE_BAUD = 9600; // Your XBee's baud (9600 is default)
const int SERIAL_BAUD = 4800; // Your XBee's baud (9600 is default)
SoftwareSerial xB(XB_RX, XB_TX);// Designates pins on arduino board to be used for communication
///////////////////////////
// Variable Declarations //
///////////////////////////
const int tot_sensors = VSensors + ISensors; // The total number of sensors being measured by board
float V[tot_sensors]; // Input voltage for sensor [i]
float V_out[tot_sensors]; // Used to output voltage at arduino board for sensor[i]
int MSB[tot_sensors]; // Voltage sensors MSB
int LSB[tot_sensors]; // Voltage sensors LSB
int MSB_I; // Current sensor MSB
int LSB_I; // Current sensor LSB
float current[tot_sensors]; // Calculated to print current to monitor
float V_in[tot_sensors]; // The combination of the MSB and LSB for current
//float current_out; // Calculated to output voltage at arduino board
int debugLED = 13; // Used to detect if information is being sent to Arduino board (blinks when received)
//int outPin[tot_sensors]; // Creates an array of output pins the size of the # of sensors being used
int freq; // Frequency to output a 50% duty cycle to mimic a 0-5V output
int outPin[] = {3, 5, 6, 9, 10}; // Pins 3,5,6,9, and 10 can output PWM to be detected by logger
///////////
// Setup //
///////////
void setup() {
Serial.begin(SERIAL_BAUD); // Sets the baud rate for communication via terminal monitor on computer
xB.begin(XBEE_BAUD); // Sets the baud rate for communication with the Transmitting Xbee radio
Serial.print(VSensors); Serial.println(" # of Vsensors");
Serial.print(ISensors); Serial.println(" # of Isensors");
Serial.print(tot_sensors); Serial.println(" # of sensors");
}
//////////
// Loop //
//////////
void loop() {
// Diagnostics testing, uncomment below to test communications and see all packets being delivered
// Comment out everything below this diagnostics though using a /* at the beginning and */ at the end
while (!xB.available()) {
}
/**/
// make sure everything we need is in the buffer packet
if (xB.available() >= 21) { // If available # of bytes is greater than 21 proceed
//while (xB.available()) {
if (xB.read() == 0x7E) { // Start byte always = 126 or 7E in Hex
if (xB.read() == 0x00) { // First bit of packet length, typically 0
//if (xB.read() == (14 + (tot_sensors * 2))) {// Second bit of packet length, in this case it is # of inputs * 2 + 14 preceeding bits
if (xB.read() == (15)) {
if (xB.read() == 0x90) { // 144(90 hex) seems to be the golden value here while 146 is an escaping character and should be avoided
// blink debug LED to indicate when data is received
digitalWrite(debugLED, HIGH);
delay(10);
digitalWrite(debugLED, LOW);
// read the variables that we're not using out of the buffer and discard
for (int i = 0; i < 11; i++) { // 11 means there are 11 variables between the "144" above and our "Data" bytes
byte discard = xB.read(); // Discards bytes
}
byte i = xB.read();
if (i < VSensors) {
readVoltage(i);
}
else {
readCurrent(i);
}
////////////////////
// Voltage Output //
////////////////////
switch (outputType) {
case 1: // Analog voltage output on outPin{i}
Serial.println("Case 1 has been entered");
analogWrite(outPin[i], V_out[i]); // Ouputs sensor voltage(i) to pin (i+5)
break;
case 2: // PWM output on outPin{i}
Serial.println("Case 2 has been entered");
// Tone can only be between 31 and 4978 hz
freq = (i * 500 + 500) + 500 * (V[i] / 5); // 1st output starts at 500hz, 2nd @ 1000hz etc.
tone(3, freq);
Serial.print("V["); Serial.print(i); Serial.print("] is "); Serial.println(V[i]);
Serial.print("Frequency is "); Serial.println(freq);
Serial.print("i = "); Serial.println(i);
Serial.print("Output pin is "); Serial.println(outPin[i]);
break;
default: // outputType has not been declared
Serial.print("outputType has not been declared");
break;
}
Serial.println("");
}
}
}
}
}
}
//////////////////
// Read Voltage //
//////////////////
void readVoltage(int i) {
// Begin to read the 2 part bytes sent from the other radio
//for (int i = 0; i < VSensors; i++) { // Begins loop the size of # of input sensors 1-5
MSB[i] = xB.read(); // Reads the MSB of input[i]
LSB[i] = xB.read(); // Reads the LSB of input[i]
V[i] = LSB[i] + (MSB[i] * 256); // Converts multiple 0-256 values of MSB&LSB to a single 0-1024 value
V_out[i] = V[i] / 4; // Converts single 0-1024 value (V[i]) to single 0-256 value for voltage output
V[i] = map(V[i], 0, 1023, 0, 500);// Maps the 0-1024 to 0-500 for serial printing in terms of voltage display
V[i] = V[i] / 100; // Arduino does not like changing from an int to a float in the same line??? 500V now equals 5V
Serial.print("Input_"); Serial.print(i); Serial.print(" = "); Serial.print(V[i]); Serial.println(" Volts ");
}
//////////////////
// Read Current //
//////////////////
void readCurrent(int i) {
MSB[i] = xB.read(); // Reads the MSB of the current input
LSB[i] = xB.read(); // Reads the LSB of the current input
V[i] = LSB[i] + (MSB[i] * 256);
V_out[i] = V[i] / 4; // Converts single 0-1024 value (V[i]) to single 0-256 value for voltage output
V[i] = map(V[i], 0, 1023, 0, 500);
V[i] /= 100;
current[i] = 73.3 * (V[i] + 2.5) / 5 - 36.65;
Serial.print("V at input "); Serial.print(i); Serial.print(" = "); Serial.println(V[i]);
Serial.print("Current at input "); Serial.print(i); Serial.print(" = "); Serial.println(current[i]);
Serial.print("Bits out at pin "); Serial.print(outPin[i]); Serial.print(" = "); Serial.println(V_out[i]);
//current_out = current * 100; // Multiply by 100 to get rid of decimal places
//current_out = map(current_out, 0 , 500, 0 , 255); // Map the 0-5 V to 0-255 for voltage output on arduino pins
//analogWrite(current_pin, current_out); // Outputs voltage corresponding to input current on other board (0.45A = 0.45V)
Serial.println(" "); // Creates new line for serial debugging purposes
}
//////////
// END! //
//////////