Reading an IO register and doing a byte operation

With an Arduino UNO R3, I was wanting to monitor 3 different inputs on 3 pins. With an interrupt I would have the ISR use a switch statement to call different functions.

I wanted to read a port register (Port B?) and using byte (low or high) read the value and use that for the cases.

My question is how do I read a port IO register and not just a pin read

Welcome to the forum

This may be of interest https://docs.arduino.cc/retired/hacking/software/PortManipulation/

Followed by this https://docs.arduino.cc/learn/programming/bit-math/

This is the only reference on that page to reading an input register...

PIND is the input register variable It will read all of the digital input pins at the same time.

A long lively topic on the Forum about your very question:

Which page are you referring to ?

https://docs.arduino.cc/retired/hacking/software/PortManipulation/

(sorry.... your second post was not up when I started to post...)

PINB is the name of the Port B input register, here I assign it to the new variable bInputs:

unsigned char bInputs = PINB;

but until you present some code, I remain unconvinced that you need to use interrupts.

And reading the entire port at a time is fun, but this, too, is not usually terribly necessary.

Both choices will make your code harder to understand, probably, until we see what you doing.

a7

Understood

I realised after posting the first link that although it mentioned the registers there was no detail on how to read individual bits. I considered editing the post to add the second link but you never know whether someone has already read a post so decided to add a second one

I was not clear on what or when the interrupts were used, sorry for not being clear.
I am using a DS3231 with the alarm triggering the interrupt at specific times. The ISR reads the alarm time to decide where to move a device to a new location.

There are 3 switch sensors for different positions and I wanted to read a group of pins (UNO-R3 pins 4,5,6 &7 which is grounded) and the correct binary value would let me know I have arrived. I would activate a motor drive relay using a while != value instruction. it seamed easiest to pass in the value associated with that position as part of the while instruction. Right now I am having trouble with the ISR routine. Ill be adding another question for that problem.

Thanks for your great help.

If you mean read from the DS3231, one cannot do I2C operations within an ISR.

This project is very unlikely to require interrupts, and we don't recommend that new users try, as the attempt typically introduces more problems than it solves.

The interrupt routine should only set an indicate the interrupt occurred. The loop() should check the indicator and do the actual processing. From one of my projects...


 // volatile because it is shared with the interrupt routine
volatile boolean timerInterupt = true;   // force initial processing 
const uint8_t INTERRUPT_PIN = A7;  //Mayfly defaults the RTC interrupt to pin A7
/********************************************************************
*
* Interrupt service routine for interrupt from RTC
* 
* ********************************************************************/ 
ISR(PCINT0_vect)  // Predefined name for interrupts on Port A, PCINT0 - PCINT7
{
    // Keep this as short as possible. 
    if (!digitalRead(INTERRUPT_PIN)) {
        timerInterupt = true;  // we are only interested in the high to low change
    }
}

.....
// In loop()

//
// Handle RTC interrupts
//     
    if (timerInterupt) {  
          
      // This clears the interrupt flag in status register of the clock
      // The next timed interrupt will not be sent until this is cleared
      // get alarm flags - note that this may generate a low to high pin change interrupt 
      DS3231AlarmFlag flag = Rtc.LatchAlarmsTriggeredFlags();  

      LOG_DEBUG( << "Alarm flags " <<flag << endl);
      // Get current date/time
      present = Rtc.GetDateTime(); //get the current date-time
          
      if ((flag & DS3231AlarmFlag_Alarm1){ // Handle data collection interrupt

.....
     }
// much later....
     if (flag & DS3231AlarmFlag_Alarm2) { // Handle WiFi sleep timer interrupt

I submitted another question " [UNO R3 interrupt from DS3231 RTC problem] before I saw your reply.
UNO R3 interrupt from DS3231 RTC problem)

I noticed that you are using the RTClib library and I am using the wire library. I tried to use the RTClib, but I was having issues (Ignorance on my part).

I will try and do what you suggest with setting a flag

I use this RTC library. Others may have different options.

// Real time clock
#include <RtcDS3231.h>    // from "Rtc by Makuna" in library manager
RtcDS3231<TwoWire> Rtc(Wire);  // Construct RTC object

In setup()

    Wire.begin();    // Set up I2C base functions
     
     // Set up real time clock/calendar
    Rtc.Begin();
    Rtc.SetIsRunning(true);
    Rtc.Enable32kHzPin(false);
    Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmBoth);

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.