2

I'm trying to implement interrupts in my program. It essentially is constantly reading a photo-resistor and if it exceeds a certain threshold, we should send an update to our database. I'm struggling to understand how to do interrupts on a analog pin. I've tried reading this but honestly, it doesn't make much sense. Could anyone give me some advice? Here's out code.

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Initally send out false state
  sendState("18:FE:34:F4:D0:AF", false, false);
}

void loop() {

  if(analogRead(A0) < 20) {
    sendState("18:FE:34:F4:D0:AF", false, true);
    lastState = true;
    Serial.println("Waiting....");
    delay(15000);
  } else if(lastState == true){
    sendState("18:FE:34:F4:D0:AF", false, false);
    lastState = false;
  }

}

void sendState(String address, boolean lights, boolean occupied) {

  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  String lightsStr = (lights) ? "true" : "false";
  String occupiedStr = (occupied) ? "true" : "false";
  String json = "{\"MACAddress\":\"" + address + "\", \"occupied\":" + occupiedStr + "}";

  String postData;
  postData += "POST /sensor HTTP/1.0 \r\n";
  postData += "X-Parse-REST-API-Key: " + API_KEY + "\r\n";
  postData += "Content-Type: application/json \r\n";
  postData += "Host: " + String(host) + " \r\n";
  postData += "Content-Length: " + String(json.length()) + "\r\n\r\n";
  postData += json;

  // Send the postdata to the server.
  client.print(postData);

  delay(1000);

  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }

  Serial.println();
  Serial.println("Closing connection!");
} 
2

Interrupts are a tricky concept to get, you have to be mindful of so many things (in bigger projects).

Have a quick look on youtube for some tutorials, there are a heap out there.

Having said all that, your code above isn't using interrupts at all. And you have these big delays, does the code work as published?

I would suggest you rework the code into more of a state machine and have a single loop. ditch all the delays (except for your setup, that's fine) and go along the lines of:

setup

set a variable for current timer value and have a constant defined for your update interval

loop

  • read sensor (consider constantly reading, or reading it more often than the information is sent, and average it out)
  • anything on the serial port?
    • go read it
  • check timer against old timer and interval
  • interval exceeded
    • send averaged value

using interrupts

You could use interrupts but the thing to consider is that they can be run AT ANY TIME. your code must be interrupt-able which whilst isn't too hard, needs special consideration in relation to delays, reading 16bit values, not having delays in the interrupt, status register changes, a whole host of others.

There are two types of interrupt, those that are driven by a change in input and those that are time based. You don't really want the change in state on this one because you would normally want to monitor it constantly anyway, but it is certainly doable.

In both time based and external input, you would have the interrupt set a flag that gets acted upon in your main loop.

sorry for not providing more info at this time, screaming kids :(

1

You can use the inbuilt analog comparator to generate an interrupt when a certain threshold is reached. Example circuit (reference voltage on D7, voltage under test on D6):

Analog comparator schematic


Example code for the Uno:

volatile boolean triggered;

ISR (ANALOG_COMP_vect)
  {
  triggered = true;
  }

void setup ()
  {
  Serial.begin (115200);
  Serial.println ("Started.");
  ADCSRB = 0;           // (Disable) ACME: Analog Comparator Multiplexer Enable
  ACSR =  bit (ACI)     // (Clear) Analog Comparator Interrupt Flag
        | bit (ACIE)    // Analog Comparator Interrupt Enable
        | bit (ACIS1);  // ACIS1, ACIS0: Analog Comparator Interrupt Mode Select (trigger on falling edge)
   }  // end of setup

void loop ()
  {
  if (triggered)
    {
    Serial.println ("Triggered!"); 
    triggered = false;
    }

  }  // end of loop

The incoming voltage is on the AIN0 (positive) pin which is pin 12 on the actual chip, and D6 on the Arduino board. The reference voltage (negative) pin is pin 13 on the chip, and D7 on the Arduino.

My example does not address the issue of transmitting the results, but that is the easy bit. You might need to build in a test so that you don't transmit the information thousands of times a second.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.