Jump to content

Another Arduino thread..


davidb

Featured Posts

I have hat some great advice on this thread but  I'm still not getting it right. Seeing that thread was getting so big, I thought I would start a fresh one sorry about that. I thought I would try and get the project behind me before we get boating again this summer, hopefully.

 

We are booked to cross on the Ribble Link down to Tarleton on the 16th of April, then on towards Skipton, looking forward to that, fingers crossed.

 

I have run the millis sketch as a trial and now have a reasonable idea of how it works, and the issues when it comes to rollover won't be a problem anyway because the controller powers down when the boiler goes out , and that will happen at least once a fortnight, so millis will reset.

 

The problem I have is how to get the timer working after a button press to cancel an alarm LED? I have been trialling some code to make the response after the button is relaeased so the Pin is going from 1 to 0 in order to avoid bounce.

 

I somehow need to get another " if" statement within these two lines

 

if (ledState == LOW)
      ledState = HIGH; 

 

  I think, and then the loop can  keep going round again to check whether the alarm LED should still be lit?
 
  if(currentMillis - previousMillis > interval) {

  if((currentMillis - previousMillis > interval) || (currentMillis < previousMillis)) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   
 
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
 
    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }

 

I have got rid of all the delay(dts) from the original and it is looping very fast.

 

I am not brave enough to post on the Arduino.cc forum, I'm afraid they seem to jump on newbies in a very harsh way.

 

cheers, David

 

 

 

 

Link to comment
Share on other sites

Very clever how you have linked a totally irrelevant microcontroller question into a Ribble link crossing ?

 

I have hugely cut down on my drinking of late (Telling off from Doctor) but tonight is a Drinking Night, so if nobody else helps I will look at your code tomoro. ?

 

..............Dave

Link to comment
Share on other sites

Not quite sure what you are doing here, the code is not a switch debouncer but just flashes the LED with equal on and off times, these times are set by the value of "interval" so I assume you have given it a suitable value, we are working in milliseconds so 500 will give a 1 second cycle.

Currentmillis and previousmillis should be unsigned longs.  You need to set a value with something like

currentmillis = millis()....these reads the time (in milliseconds).

 

If you are not worried about rollover then the green statment (IF clause) is fine, no need for the Red one.

 

So essentially it looks like you are not reading the value of millis()

 

...................Dave

Link to comment
Share on other sites

Can you post the whole sketch? There are some questions @dmr has asked on the data types for the times for example that should be earlier in the sketch. Could well be that the problem is elsewhere within the sketch.

If you look on the post editor, you'll see an option that looks like </>, which will bring up a box within which the code can be posted. There is a drop down at the lower right of the code entry box. Change it from html to C Languages. This will do colour highlighting that make it easier for others to read and interpret what you've done.

 

Jen

Link to comment
Share on other sites

thanks for those, I will make a clone of the sketch and simplify it down to the bit that is causing the problem, compile it and get it all happy, test it, then report back with all the code. cheers, David

Link to comment
Share on other sites

 

 //   file name:  millis23Mar
 
 int myPin = A2; // INPUT Analogue Sensor
   int stoke = 2; // INPUT Stoking Temp Sensor (Bottom of store)
   int houseUFH = 3; // OUTPUT UFH Relay
    int runPin = 4; // INPUT Heat Available Temp Sensor (Top of store)
    
       int alarm = 7; // OUTPUT Alarm Light Relay
        
         int veryHot = 9; // INPUT  Boiler too hot
          int logStoreUFH = 10; // OUTPUT Log Store UFH Relay
           int butt = 12; // INTPUT from Cancel Button
          
          int ledPin = 13; // OUTPUT Indicator LED
          
int currentMillis = (0);


unsigned long previousMillis = 0;        // will store last time LED was updated

const long interval = 40000;           // interval at which to operate (milliseconds)
           
      int dt = 500; // Delay of 500 milisecs

void setup() {
  Serial.begin(9600);
  
    pinMode(myPin,INPUT);          //  pin A2
     pinMode(stoke,INPUT);         // stat acts 70deg    pin 2
      pinMode(houseUFH, OUTPUT);   // Yellow Relay Wire  pin 3
       pinMode(runPin, INPUT);     // stat acts at 56deg    pin 4
        
          pinMode(alarm, OUTPUT);         // Blue Relay Wire   pin 7
           
            pinMode(veryHot, INPUT);        // stat acts at 85deg   pin 9
             pinMode(logStoreUFH, OUTPUT); // Green Relay Wire  pin 10
             pinMode(butt,INPUT);           //  cancel button  pin12
              pinMode(ledPin, OUTPUT);     // Indicator LED     pin13
               
}

void loop() {

delay (dt);

unsigned long currentMillis = millis();

int analog = analogRead(myPin);    // Reads data from myPin (A2) pin and puts in analog Int
int readRun = digitalRead(runPin);  // Reads data from runPin (4) and puts it in readRun Int
int readStoke = digitalRead(stoke); // Reads data from stoke (2) and puts in readStoke Int
int readAlarm = digitalRead(alarm); // Reads data from alarm (7) and puts in readAlarm Int
int readHot = digitalRead(veryHot);      // Reads data from veryHot (9) and puts it in readHot Int
int readButt = digitalRead(butt);  // Reads data from butt (12) and puts it in readButt Int


if (readStoke == 0){
                   
  Serial.println("Boiler Requires Stoking");
   digitalWrite(ledPin,HIGH);                 // starts indicator LED flashing
           delay (dt);
         digitalWrite(ledPin,LOW);
          delay (dt);         // ends indicator LED flashing
  digitalWrite(alarm,HIGH); }    // lights alarm led on pin 7
 
else{
  digitalWrite(ledPin,LOW);
  digitalWrite(alarm,LOW); }
  
  Serial.print("   Millis  =   ");
Serial.println(millis());

  
if (readButt == HIGH) {

  digitalWrite(ledPin,LOW);
  digitalWrite(alarm,LOW);
}

  if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED
    digitalWrite(alarm,LOW);
    
  }  

             }
 

 

I hope that code shows properly, it has compiled OK, but pressing the button only extinguishes the LEDs for one loop

 

Edited by davidb
untidy
Link to comment
Share on other sites

First look

With the inputs. Do you use external pull up, or pull down resistors at all? Without pull up, or pull down resistors, you can get weird spurious triggerings with on/off inputs like buttons and similar where one side is open circuit. Possibly result in what you are seeing, but poor practice anyway. Is the button press going to give you a HIGH, or LOW signal? It looks like a high one. If you don't already have pullu p/down resistors, I'd wire them to go to 0V when pressed, so Pin > button > Gnd, then define them as INPUT_PULLUP and make use of the built in pull up resistors in the Arduino. After doing that, the if(readButt ==LOW){ is used to turn off the alarm and LED.

 

pinMode(butt,INPUT_PULLUP); //for example.

 

I'd set ledPin LOW in the setup section, after the pinModes are defined, so that your Arduino outputs are in a known state when it is powered up. The same for other outputs like relays. Relays are better wired to operate when LOW, the Arduino is better at sinking current to zero than it is at sourcing 5V. Similarly for external LED's you might want to drive.

 

Near the top you are defining currentMillis as an integer (INT) and setting it to zero, then in the loop, you redefine it as a an unsigned long and set it to millis(). Shouldn't make any difference as the unsigned long overrides the int, but better to define it as an unsigned long in the first place. Not a major problem, but worth doing.

 

Sure I'll spot more later.
Jen

 

Link to comment
Share on other sites

Do you use external pull up, or pull down resistors at all?"     Yes they all have pull down external resistors

 

"Is the button press going to give you a HIGH, or LOW signal?"   it is currently giving HIGH on pressed

 

"if(readButt ==LOW){ is used to turn off the alarm and LED."   I shall change it over to that tonight, thanks

 

The relays are already wired to operate when LOW - I could't understand why they were like that when I bought them, but I do now.

 

"Near the top you are defining currentMillis as an integer (INT) and setting it to zero, then in the loop, you redefine it as a an unsigned long and set it to millis()."

 

"This will do colour highlighting that make it easier for others to read and interpret what you've done. "  The colouring didn't seem to work?

 

Must try harder!

 

Lots to do now, thanks a lot, D

 

 

 

Link to comment
Share on other sites

14 hours ago, davidb said:

I hope that code shows properly, it has compiled OK, but pressing the button only extinguishes the LEDs for one loop

If readStoke is still zero, then that is what I'd expect. The LED will just flash again and the alarm start the next time it loops round. At the moment, the cancel button doesn't really do much. The LED flashing is controlled by the Stoke input.

What is it you want to do? Cancel the alarm and flashing LED when you notice it, while the temperature is still low?

 

1 hour ago, davidb said:

Do you use external pull up, or pull down resistors at all?"     Yes they all have pull down external resistors

Thanks. It now makes much more sense to me.

 

1 hour ago, davidb said:

"This will do colour highlighting that make it easier for others to read and interpret what you've done. "  The colouring didn't seem to work?

Seems to work here. comments are in red, Blue purple and red in there too.

Link to comment
Share on other sites

28 minutes ago, Jen-in-Wellies said:

Cancel the alarm and flashing LED when you notice it, while the temperature is still low?

Yes, that's the plan - to cancel it for 20 minutes because after stoking it takes at least that long to take effect.

 

I need to save up and buy a colour computer. Black and white ones are a bit dated now?

Link to comment
Share on other sites

42 minutes ago, davidb said:

Yes, that's the plan - to cancel it for 20 minutes because after stoking it takes at least that long to take effect.

 

 

One way of doing it:

Define another variable before the loop{} that will hold a value if the cancel button has been pressed.

int buttonPressed = 0;

 

Then in the loop looking at if the temperature is too low have the criteria that the cancel button has also not been pressed.

if ((readStoke == 0) && (buttonPressed == 0){

 

Then when the button is pressed set buttonPressed to 1.

if (readButt == HIGH) {
  buttonPressed = 1;
  digitalWrite(ledPin,LOW);
  digitalWrite(alarm,LOW);
}

 

Then add a thing to reset buttonPressed to zero when the temperature recovers, so it will alarm again the next time it drops too low.

 

if (readStoke == 1){
  buttonPressed = 0;
}
Link to comment
Share on other sites

The first computer  (IBM 4-72)  I used ate 80 column punched cards and gave the response on a pile of fan-fold paper about 3 times as long as it needed to be.

 

Commonly it said things like  "Syntax Error" and not much more.

 

N

Link to comment
Share on other sites

Have you got unbalanced { } s?  Are you outside a brace pair?

3 hours ago, BEngo said:

The first computer  (IBM 4-72)  I used ate 80 column punched cards and gave the response on a pile of fan-fold paper about 3 times as long as it needed to be.

 

Commonly it said things like  "Syntax Error" and not much more.

 

N

If it was a 4-72 then it was System 4 not an IBM machine!!!

Link to comment
Share on other sites

The error reporting from the Arduino C compiler is widely ridiculed for giving none too helpful messages.

As said above, this error is likely due to a previous error and its not till the compiler gets to your IF that it deduces something previous has gone wrong.

 

............Dave

 

Link to comment
Share on other sites

 
 
 //millis23Mar
 
 int myPin = A2; // INPUT Analogue Sensor
   int stoke = 2; // INPUT Stoking Temp Sensor (Bottom of store)
   int houseUFH = 3; // OUTPUT UFH Relay
    int runPin = 4; // INPUT Heat Available Temp Sensor (Top of store)
    
       int alarm = 7; // OUTPUT Alarm Light Relay
        
         int veryHot = 9; // INPUT  Boiler too hot
          int logStoreUFH = 10; // OUTPUT Log Store UFH Relay
           int butt = 12; // INTPUT from Cancel Button
            int buttonPressed = 0;
             int ledPin = 13; // OUTPUT Indicator LED
              

unsigned long previousMillis = 0;        // will store last time LED was updated

const long interval = 40000;           // interval at which to blink (milliseconds)
           
      int dt = 100; // Delay of 500 milisecs

void setup() {
  Serial.begin(9600);
  
    pinMode(myPin,INPUT);          //  pin A2
     pinMode(stoke,INPUT);         // stat acts 70deg    pin 2
      pinMode(houseUFH, OUTPUT);   // Yellow Relay Wire  pin 3
       pinMode(runPin, INPUT);     // stat acts at 56deg    pin 4
        
          pinMode(alarm, OUTPUT);         // Blue Relay Wire   pin 7
           
            pinMode(veryHot, INPUT);        // stat acts at 85deg   pin 9
             pinMode(logStoreUFH, OUTPUT); // Green Relay Wire  pin 10
             pinMode(butt,INPUT_PULLUP);           //  cancel button  pin12
              pinMode(ledPin, OUTPUT);     // Indicator LED     pin13
         
}

void loop() {

delay (dt*5);





unsigned long currentMillis = millis();

int analog = analogRead(myPin);    // Reads data from myPin (A2) pin and puts in analog Int
int readRun = digitalRead(runPin);  // Reads data from runPin (4) and puts it in readRun Int
int readStoke = digitalRead(stoke); // Reads data from stoke (2) and puts in readStoke Int
int readAlarm = digitalRead(alarm); // Reads data from alarm (7) and puts in readAlarm Int
int readHot = digitalRead(veryHot);      // Reads data from veryHot (9) and puts it in readHot Int
int readButt = digitalRead(butt);  // Reads data from butt (12) and puts it in readButt Int

Serial.print("   Stoke  =   ");
Serial.println(readStoke);
Serial.print("   button pressed  =   ");
Serial.println(readButt);
Serial.print("   Millis  =   ");
Serial.println(millis());

if ((readStoke == 0) && (readButt == 1)){
                   
  Serial.println("Boiler Requires Stoking");
   digitalWrite(ledPin,HIGH);                 // starts indicator LED flashing
           delay (dt);
         digitalWrite(ledPin,LOW);
          delay (dt);         // ends indicator LED flashing
  digitalWrite(alarm,HIGH); }    // lights alarm light pin 7
  
   if (readButt == HIGH) {
  buttonPressed = 0;
 
digitalWrite(alarm,LOW);
  
  if(currentMillis - previousMillis >= interval) { // save the last time
    
   digitalWrite(alarm,LOW);}
else{
  digitalWrite(ledPin,LOW);
  digitalWrite(alarm,LOW); }
  }
   }
   
   

             
            
 

So that is the current sketch, plenty of delays so I can read that the button press now gives 0 and other stuff in the serial monitor.

 

I am not bothered at present about the ledPin, its just the alarm I would like to sort.

 

Currently, when readStoke=0  the led is flashing about twice a second and the alarm led is not working at all

 

While the button is held down, the only effect is that it stops the ledPin flashing

 

I'm sure all my problems are in the last 20 lines.

 

thanks for looking, D

Edited by davidb
to add explanation
Link to comment
Share on other sites

 

Your formatting is a mess which makes it hard to see at a glance what your conditionals do - try (Tools -> Auto Format) in your IDE then repost the code please.

 

Also add more comments so we know what you are trying to achieve in each section:

 

I think you've got your process flow confused.  Is this what you are trying to achieve? :

 

loop
    if (boiler too cold, nothing to do with reset button)
    
        if (last reset outside permitted interval)
            set alarm
        end if
    
        if (reset button pressed)
            cancel alarm
            set time since last reset to now
        end if
        
    else 
        cancel alarm (ie boiler temp OK)
    end if
end loop

    

 

 

 

 

 

 

Edited by TheBiscuits
Add a bit
Link to comment
Share on other sites

loop

if (boiler too cold, nothing to do with reset button)


if (last reset outside permitted interval, ie 20minute delay)

set alarm

end if


if (reset button pressed)

cancel alarm


set time since last reset to now

end if


else cancel alarm (ie boiler temp OK)

end if

end loop

 

yes, the above is correct, thanks, I'll try the auto formatting tonight, cheers, David

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.