Problems with Hardware Interrupts, Polling (Making a Colloidal Silver Generator)

Hello all,

I’m trying to make a colloidal silver generator with an Arduino-controlled timer, and I’m getting tangled up in the code. I’ve been struggling with it for four days solid and I need help with the interrupt and probably with some of the logic. My own built-in neural ‘microprocessor’ was damaged years ago by Viral Encephalitis (like Meningitis only nastier), and I can only keep so much in my head at one time before I feel sick and my head starts to seriously throb. I thought I would be able to manage one knob and one switch worth of logic, but it’s more complicated than I thought.

I’m trying to make it so that I can set the number of hours for the timer to run using an encoder, then start it (and also pause it if necessary) using a NO pushbutton switch, and display the encoder input on LCD, changing to timer countdown on LCD once the timer has started. I have the KY-040 rotary encoder/switch combo connected up to an Arduino Mega2560 using hardware debouncing (47uF caps to earth). I’ve got it so as I can set the time and start the timer and have it count down, but getting it to pause and update the screen, then start again where it left off (in the meantime ignoring all irrelevant encoder input), and also stop counting down when it gets to zero is where I’m stuck.

I did it originally with polling the switch during the loop function, but it was very laggy, so I had a go at writing a simple interrupt and now it won’t work at all (i.e. the timer no longer starts counting down, though the output gets switched even without the timer being set). It’s a case of one step forwards and three backwards, and I feel absolutely snowed under with it. Any help in pulling it all together and making it work would be very much appreciated.

I’ve posted the code as an attachment, as it was a bit more than 9000 characters long including comments, and I didn’t want to leave those out.

Lachlan

Colloidal Silver Timer.txt (13.7 KB)

int                   readSW = HIGH;                                   // If switch SW has been pressed, set to 1. Any variable within an interrupt must be volatile, as it's only temporary.

I see a conflict between the code and the comment. It may not be causing a problem but it should be fixed. Why is the readSW variable declared as an int when it will only ever hold a value less that 255 ?

 pinMode(PinSW, INPUT);                 // Put the pin the switch is connected to into input mode

Is the switch wired correctly? How IS the switch wired?

 pinMode(switchOutputPin, OUTPUT);      // Set the pin controlling the switch to output duty

What switch? A switch is normally an input device.

      updateKnob();      // Read from encoder knob

In a function called update? I am positive that the function needs a better name.

You almost certainly want to read a switch using polling and read an encoder using interrupts, not the other way around.

 int                   readSW = HIGH;                                   // If switch SW has been pressed, set to 1. Any variable within an interrupt must be volatile, as it's only temporary.

I don't understand this comment. The variable is not volatile.


    if((digitalRead(PinSW == LOW)) && (pausedState == true))

That bracket is in the wrong place. PinSW is 20, so it won't also be equal to zero. Thus the statement following the "if" is never executed.

Paul, Nick, Bob,

Thanks for replying. You seem to have picked up some important stuff. I feel too ill to answer your posts tonight (I'm a chronic invalid thanks to the encephalitis). Will try to write tomorrow.

Regards,
Lachlan

Hello again all,

Bob, yes, it should just be a byte. I'm not a very experienced programmer (ahem... I'm not a programmer at all).

Paul, The switch is wired from pin 20 of my Mega2560 with a 10,000 pull-up resistor. It seems to work all right, or at least it did before I tried to add an interrupt. I'm more confident with the electronics side of things, since I trained originally as an electronics repair tech (decades ago and 100% analogue, with valves, trannies and what-have-you, but still … ).

Nick, You're right, I didn't spot that. I think I updated my code and forgot to update the comments there. I originally had an interrupt in it but couldn't get it working and tried without it, but it's too slow without it I think).

Regards,
Lachlan

Bob, yes, it should just be a byte. I'm not a very experienced programmer (ahem... I'm not a programmer at all).

Of more concern is that the variable is not declared volatile despite the comment.

UKHeliBob:
Of more concern is that the variable is not declared volatile despite the comment.

Are you saying it should be?

Lachlan

Are you saying it should be?

Well, duh!

Gairlochan:
Are you saying it should be?

Lachlan

Have you actually read the replies in this thread, or the comment for that matter ?

Yes, I've read the replies, and tried to answer them as best I could in between dealing with a seizure and a 3 day migraine, plus the usual substantial memory, information processing and comprehension problems which I face every day, plus the usual problems of being bedridden etc ad nauseam. All of which is substantially aggravated by menopause (which I'm going through atm), as neurological problems like seizures often are. I think I mentioned that I'm a (very lucky) survivor of Encephalitis, big brother of Meningitis. Google 'encephalitis' if you want an idea of the damage it can do your brain and the havoc it can cause in your life (if you're lucky enough not to be a vegetable or dead from the brain damage). You don't just recover from it and carry on, as with most other acute illnesses.

I'm lucky to be able to programme at all, and stupid, obvious mistakes that make my brain throb and swim to even try to think out myself are the reason I asked for help here. I guess I've had all the help I'm going to get, so thanks all for the points you've made, and I'll see what I can do with the info once the latest migraine calms down sufficiently. But just the moment, even thinking about programming makes me (more) ill.

Regards,
Lachlan

Well, don't give up just yet. If you'll bear with us, it can be frustrating when we make suggestions that appear to be ignored.

I suggest you start with a simple project that uses interrupts, and then armed with the knowledge and confidence that gives you, go back to your main project.

You may find this useful: Gammon Forum : Electronics : Microprocessors : Interrupts

For a simple example of timing something with interrupts, here is some code I wrote a while back that times a ball rolling down a ramp between two light-sensors:

const byte LED = 12;
const byte photoTransistor = 2;

unsigned long startTime;
volatile unsigned long elapsedTime;
volatile boolean done;

void ballPasses ()
{
  // if low, ball is in front of light
  if (digitalRead (photoTransistor) == LOW)
    {
    startTime = micros (); 
    }
  else
    {
    elapsedTime = micros () - startTime;  
    done = true;
    }
    
  digitalWrite (LED, !digitalRead (LED));  
}


void setup ()
{
  Serial.begin (115200);
  Serial.println ("Timer sketch started.");  
  pinMode (LED, OUTPUT);
  attachInterrupt (0, ballPasses, CHANGE);
}

void loop ()
  {
  if (!done)
    return;
    
  Serial.print ("Time taken = ");
  Serial.print (elapsedTime);
  Serial.println (" uS");
  done = false;
  }