Hello
I have adapted a few sketches in the past but this is my first "complicated" one. I am having problems with the digital write on my working sketch but it works OK on a test sketch.
I have an Uno with a network shield fitted ( that is another problem I will probably come back to you about ) and a LCD screen.
I also have three external sensors going through voltage dividers supplying a voltage between 0 and 4.6V.
This is my simple test sketch that works - turns the output on and off ( no external signal etc. ):
const int solenoid = 19;
void setup() {
Serial.begin(9600);
pinMode(solenoid, OUTPUT);
digitalWrite(solenoid, LOW);
}
void loop()
{
digitalWrite(solenoid, HIGH);
Serial.println();
Serial.println("Solenoid on");
Serial.print("Solenoid read state = ");
Serial.println(bitRead(PORTD,solenoid));
delay(5000);
digitalWrite(solenoid, LOW);
Serial.println();
Serial.println("Solenoid off");
Serial.print("Solenoid read state = ");
Serial.println(bitRead(PORTD,solenoid));
delay(5000);
Serial.println("_________________________________");
}
This is my working code - some of the code is quite neat as a guy at work helped me clean it up:
Currently the signal to the relay is off all the time and the Serial.println(bitRead(PORTD,solenoid)); confirms that. I assume the signal to set the pin to high is being recived as solenoidState is being set to 1 in the loop.
Any help with this would be gratefully recived as I haave spent a few days trying to get it to work ![]()
#include "ST7565.h"
// Solenoid activation settings
float pressureLowPoint=1.5;
float pressureHighPoint=5;
// number of analog samples to take per reading
#define NUM_SAMPLES 10
const static int sensorPins[] = {A2, A3, A4};
const static char * sensorNames[] = {"Pressure", "H20", "O2"};
const static char * sensorUnits[] = {"mb", "ppm", "ppm"};
const static float sensorOffsets[] = {-28,0,0};
const static float sensorMultipliers[] = {10.7,111.36,222.72};
const static int upperLimits[] = {10, 10, 10};
const static int nSensors = sizeof(sensorPins)/sizeof(int);
int sums[nSensors]; // sum of samples taken
float voltages[nSensors]; // calculated voltage
float readings[nSensors]; // scaled readings
#define EACH_SENSOR for(int i=0; i<nSensors; i++)
// Screen settings
ST7565 glcd(9, 8, 7, 6, 5);
// PWM PINS FOR THE Backlight
int redPin = 4;
int greenPin = 3;
int bluePin = 2;
//uncomment this line if using a Common Anode LED
#define COMMON_ANODE
// Solenoid relay on analogue A5
const int solenoid = 19;
int solenoidState = 0;
void setup() {
Serial.begin(9600);
// Backlight colour pins
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
// initialize and set the contrast
glcd.begin(0x20);
const char * teststr = sensorNames[0];
}
// Calculate the sensor name length
int strlen(char * str, int maxlen = 256){
int n=0;
while(str[n] != '\0') n++;
return n;
pinMode(solenoid, OUTPUT);
digitalWrite(solenoid, LOW);
}
void loop()
{
// Take a number of analog samples and add them up
EACH_SENSOR sums[i] = 0;
for (int n_samples=0; n_samples < NUM_SAMPLES; n_samples++) {
EACH_SENSOR sums[i] += analogRead(sensorPins[i]);
delay(200);
}
// calculate the voltage
// use 5.0 for a 5.0V ADC reference voltage
// 5.015V is the calibrated reference voltage
EACH_SENSOR voltages[i] = ((float)sums[i] / (float)NUM_SAMPLES * 4.97) / 1024.0;
// send voltage for display on Serial Monitor
// voltage multiplied by 11 when using voltage divider that
// divides by 11. 11.132 is the calibrated voltage divide
// value
// Calculate the volt to pressure value
EACH_SENSOR readings[i]=(voltages[i] * sensorMultipliers[i] ) + sensorOffsets[i];
EACH_SENSOR{
// Send the values to the serial display
Serial.println ();
Serial.print(sensorNames[i]);
Serial.print(" :");
Serial.print(voltages[i] * 1);
Serial.println (" V");
Serial.print(readings[i]);
Serial.println (sensorUnits[i]);
Serial.println ();
}
// If under pressure open the solenoid in mb?
// Serial.print ( "readings = ");
// Serial.println (readings[0]);
if (readings[0]<=pressureLowPoint){
digitalWrite(solenoid, HIGH);
solenoidState = 1;
}
else if(readings[0]>pressureHighPoint){
digitalWrite(solenoid, LOW);
solenoidState = 0;
}
Serial.println(solenoidState);
// Display the pin state from the regester
Serial.print("Solenoid read state = ");
Serial.println(bitRead(PORTD,solenoid)); //Reads bit 3 of register PORTD which contains the current state (high/low) of pin 3.
boolean alarm = false;
glcd.clear();
EACH_SENSOR{
// Convert value of pressure to a character to write to the screen WILL HAVE LEADING ZEROS to allow for -20mb
// Was b[4] but changed to b[4] to allow for 1000ppm - UNTESTED
char b[5]; //declaring character array moust be 1 character longer than the actual number to allow for the NULL character
String str; //declaring string
str=String((int) round(readings[i]) ); //converting integer into a string
//str=String(counter++); //converting integer into a string
str.toCharArray(b,5); //passing the value of the string to the character array
// Draw string on the screen
int row = 3*i;
glcd.drawstring(0, row, (char *) sensorNames[i]);
glcd.drawstring(strlen(sensorNames[i])*6, row, ": ");
glcd.drawstring(65, row, b);
glcd.drawstring(90, row, (char *) sensorUnits[i]);
// Change the backlight display to red on an alarm - could have two colours one for a bit over and one for a lot over?
if(readings[i] > upperLimits[i]) alarm=true;
}
if (alarm){
setColor(255, 0, 0);
}
else {
setColor(255, 255, 255);
}
glcd.display();
}
// Function to set the backlight colour
void setColor(int red, int green, int blue)
{
#ifdef COMMON_ANODE
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
#endif
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}