4

An ATMEGA328-P chip is used with a toggle switch attached to pin 8 and a momentary switch attached to pin 9. My objective is to send the following information over serial:

  1. The status of pin 8, every second.
  2. Count the number of presses of pin 9, sending the value as the counter increments

I understand that to achieve point 2 I will need to utilise interrupts, but I have become stuck in the way I am trying to use them.

I am familiar with the following code's simple style:

  1. Within the loop...
  2. Poll the status of the input
  3. Send status over serial

Code A:

const int SWITCH_1 = 8;
const int READ_INTERVAL = 1000;

int val_s1 = 0;

void setup() {
    Serial.begin(9600);
    pinMode(LED_BUILTIN, OUTPUT);

    pinMode(SWITCH_1, INPUT);
    digitalWrite(S1, HIGH);
}

void loop() {
    val_s1 = digitalRead(SWITCH_1);
    Serial.print("S1:");
    Serial.print(val_s1);
    Serial.print("\n");

    digitalWrite(LED_BUILTIN, HIGH);
    delay(10);
    digitalWrite(LED_BUILTIN, LOW);
    delay(READ_INTERVAL);
}

When introducing the concept of interrupts, I have tried to retain the simplistic style of code A for testing purposes. The next snipped attempts to achieve the following:

  1. Attach an interrupt to pin 9 when the voltage rises
  2. No need for loop function (?)
  3. Within interrupt callback function...
  4. Increment the counter
  5. Send the counter value over serial

Code B:

void c1_rise();

const int COUNTER_1 = 9;
const int READ_INTERVAL = 1000;

volatile int val_c1 = 0;

void setup() {
    Serial.begin(9600);
    pinMode(LED_BUILTIN, OUTPUT);

    pinMode(COUNTER_1, INPUT_PULLUP);
    attachInterrupt(COUNTER_1, c1_rise, RISING);
}

void loop() {
}

void c1_rise() {
    val_c1 ++;
    Serial.print("C1:");
    Serial.print(val_c1);
    Serial.print("\n");
}

I've tried to learn where I'm going wrong, but I have become stuck and have decided to ask my questions here.

  • Observation: I expect to see some data sent over serial when the button is pressed, but actually nothing observable happens.
  • Problem 1: This might be because the interrupt isn't being attached at all.
  • Problem 2: This might be because I misunderstand the limitations of interrupt callback functions.

While trying to solve problem 1, Arduino documentation implies that to use the attachInterrupt function, parameter 1 must be an interrupt, from digitalPinToInterrupt, but if I use that function I receive the following error message: error: ‘digitalPinToInterrupt’ was not declared in this scope.

From reading up about how interrupts behave, I found problem 2: it seems that even though I have declared the integer as volatile, using Serial from within a callback function isn't allowed. This is the limit of my knowledge currently, I hope that someone can help me out.

8

You cannot use Serial inside an interrupt. Transmitting Serial relies on interrupts being available, and from inside an interrupt they aren't.

All Serial communication must be done from loop().

So you need to just count the switch toggles and check to see if that value has changed in your loop.

volatile uint32_t toggles = 0;
uint32_t old_toggles = 0;
uint32_t ts = 0;

void setup() {
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    attachInterrupt(0, toggle, RISING);
}

void loop() {
    if (toggles != old_toggles) {
        old_toggles = toggles;
        Serial.print("C1: ");
        Serial.println(toggles);
    }

    if (millis() - ts >= 1000) {
        ts = millis();
        Serial.print("S1: ");
        Serial.println(digitalRead(3));
    }
}

void toggle() {
    toggles++;
}
  • May I ask what parameter 0 of attachInterrupt should be set to? Have you set to 0 arbitrarily? I am using 9 as that is the pin the switch is attached to, but using this method still isn't triggering the callback. – Greg Nov 14 '17 at 18:21
  • 1
    I have coded that for the Uno. Pin 2 is interrupt 0. Pin 3 is interrupt 1. Select the right pins for your chosen board. – Majenko Nov 14 '17 at 18:21
  • Your answer is straight to the point, thanks for making it simple for me to understand. – Greg Nov 14 '17 at 18:36

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.