Hello,
I am trying to build and weather station and convert the measurements to analog voltages. I am using the DS15901 kit and the ADSWeather library.
I am using one arduino nano to collect measurement, which communicates, by i2c, with a second one to convert these measurements to pwm signals. I use 2 arduino because to collect measurements library uses interrupts, which interference with pwm.
The part about collecting measurements succeeded.
The problem I face is for the conversion to analog voltage. I am using the LM358 op. amp. the circuit working well.
I use digital pin 5, 10 and 11 so the pwm signal comes from different timers, but analogWrite to one pin seems to interferece with analog write of the other pin, producing wrong outputs.
I am struggling with this 2 weeks now and I cannot find the problem. Can anyone help me.
I am attaching the code and the schematic.
Thanks in advance
#include <Wire.h>
#define ANEMOMETER_SPEED_OUT_PIN 5
#define RAIN_PIN_OUT 10
#define VANE_OUT_PIN 11
#define CALC_INTERVAL 1000
unsigned long nextCalc;
unsigned long timer;
long windSpeed = 0;
long windDirection = 0;
float rainRate = 0;
long windSpeed_last;
long windDirection_last;
float rainRate_last;
//int windDir;
//int windSpeed;
int windSpeed_analogWrite = 0;
int vane_analogWrite = 0;
int rain_analogWrite = 0;
int RainBoolState;
char i2c_response[16];
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600);
pinMode(ANEMOMETER_SPEED_OUT_PIN, OUTPUT);
analogWrite(ANEMOMETER_SPEED_OUT_PIN, 0);
pinMode(RAIN_PIN_OUT, OUTPUT);
analogWrite(RAIN_PIN_OUT, 0);
pinMode(VANE_OUT_PIN, OUTPUT);
analogWrite(VANE_OUT_PIN, 0);
windSpeed_last = windSpeed;
windDirection_last = windDirection;
rainRate_last = rainRate;
nextCalc = millis() + CALC_INTERVAL;
}
void loop() {
timer = millis();
if (timer > nextCalc)
{
nextCalc = timer + CALC_INTERVAL;
memset(i2c_response, '\0', 15 * sizeof(char)); //clear i2c response
//ask for weather data form data collector on address 8 using i2c
Wire.requestFrom(8, 16); // request 16 bytes from peripheral device #8
int i = 0;
while (Wire.available()) { // peripheral may send less than requested
char c = Wire.read(); // receive a byte as character
i2c_response[i] = c;
i++;
// Serial.print(c); // print the character
}
Serial.println(i2c_response); // print the character
windSpeed = (i2c_response[4] - '0') * 100 + (i2c_response[5] - '0') * 10 + (i2c_response[6] - '0');
windDirection = (i2c_response[0] - '0') * 100 + (i2c_response[1] - '0') * 10 + (i2c_response[2] - '0');
rainRate = (i2c_response[8] - '0') * 10 + (i2c_response[9] - '0') + (i2c_response[11] - '0') * 0.1 + (i2c_response[12] - '0') * 0.01;
RainBoolState = i2c_response[14] - '0';
// rainRate=80.2;
}
//we are going to convert max of 75km to analog output
if (windSpeed > 0 && windSpeed < 5) {
windSpeed_analogWrite = 50;
}
if (windSpeed >= 5 && windSpeed < 10) {
windSpeed_analogWrite = 100;
}
if (windSpeed >= 10 && windSpeed < 30) {
windSpeed_analogWrite = 150;
}
if (windSpeed >= 30 && windSpeed < 50) {
windSpeed_analogWrite = 200;
}
if (windSpeed >= 50 && windSpeed <= 75) {
windSpeed_analogWrite = 254;
}
//we are going to convert max of 50mm per hour rain to analog output
if (rainRate <= 0 || rainRate >= 75) {
rainRate = 0;
rain_analogWrite = 0;
}
if (rainRate > 0 && rainRate < 5) {
rain_analogWrite = 50;
}
if (rainRate >= 5 && rainRate < 10) {
rain_analogWrite = 100;
}
if (rainRate >= 10 && rainRate < 20) {
rain_analogWrite = 150;
}
if (rainRate >= 20 && rainRate < 50) {
rain_analogWrite = 200;
}
if (rainRate >= 50 && rainRate < 75) {
rain_analogWrite = 254;
}
Serial.print("rain rate raw: ");
Serial.println(rainRate);
Serial.println(rain_analogWrite);
//export voltage in relation with wind direction;
if ((windDirection >= 315) || (windDirection < 45)) {
//North
vane_analogWrite = 50;
Serial.println("North");
}
else if ((windDirection >= 45) && (windDirection < 135)) {
//East
vane_analogWrite = 110;
Serial.println("East");
}
else if ((windDirection >= 135) && (windDirection < 225)) {
//South
vane_analogWrite = 180;
Serial.println("South");
}
else if ((windDirection >= 225) && (windDirection < 315)) {
//West
vane_analogWrite = 250;
Serial.println("West");
}
if (windSpeed_last != windSpeed) {
windSpeed_last = windSpeed;
analogWrite(ANEMOMETER_SPEED_OUT_PIN, windSpeed_analogWrite);
}
if (windDirection_last != windDirection) {
windDirection_last = windDirection;
analogWrite(VANE_OUT_PIN, vane_analogWrite);
}
if (rainRate_last != rainRate) {
rainRate_last = rainRate;
analogWrite(RAIN_PIN_OUT, rain_analogWrite);
}
// windSpeed / 10 will give the interger component of the wind speed
// windSpeed % 10 will give the fractional component of the wind speed
Serial.print("Wind speed: ");
Serial.print(windSpeed / 10);
Serial.print('.');
Serial.print(windSpeed % 10);
Serial.print(" ");
Serial.print("Wind Direction: ");
Serial.print(windDirection);
Serial.println("");
Serial.print("Rain Rate: ");
Serial.println(rainRate);
Serial.println("-----");
}
Schematic.pdf (2.0 MB)