seeking minimalist analog write/read code

I'm using a sensor* which works just fine with the 'ino' code below. But I need to read it on an interrupt basis, and am looking for the most 'light-weight' (fastest) sequence of instructions to place into my ISR.

The required sequence is: (1) Hold the pin HIGH to deliver energy to the sensor. (2) Switch the pin to analog input (with a 10K pullup sourcing current to the sensor) (3) Read the voltage across the sensor. (4) Return to a HIGH output state until the next time.

It is important to block interrupts for the shortest time possible.

Maybe someone who has done this already, and can save me a lot of drudgery with the Atmel spec sheet and trial-and-error testing?? [* It's an old-style Lego RCX axle-rotation sensor.]

In brief, "Is there a sequence of 'register-level' instructions to implement the following ISR for minimal service-time?"

define leftSensor A0

define leftSensorPin 14

define rightSensor A1

define rightSensorPin 15

ISR(TIMER2_OVF_vect) { pinMode(leftSensorPin, INPUT); leftData = analogRead(leftSensor); pinMode(leftSensorPin, OUTPUT); digitalWrite(leftSensorPin, HIGH); // repeat for right side newData = true; }

void setup() { pinMode(leftSensorPin, OUTPUT); digitalWrite(leftSensorPin, HIGH); // repeat for right side }

void loop() { if (newData) { // do something important } // do other stuff }

Thanks! John [FWIW: I'm fairly handy with electronics and assembler code (but C++ isn't my first language). If you have a design, I'd happily use it!]

That looks OK, except this line:

   newData = true;

For this to work, newData has to be declared globally as volatile.

When posting code, use code tags ("</>" button).

You're right.

What I'm asking, though, isn't to make THAT code work. I'm looking for something more "primitive" -- to call directly on the AVR hardware registers, and so run faster than the general Arduino read/write functions.


Use direct register access. The code often translates into single machine instructions. To set bit zero to 1 in PORTB, I use:

 PORTB |= 1;

I set & clear single bits like this, leaves the other bits unchanged: PORTB = PORTB | 0b00000001; // set bit 0, leave rest alone PORTB = PORTB & 0b11111110; // clear bit 0, leave rest alone

If you want to toggle the output bit, and you don't care what it was to start, you can write to the Input port: PINB = PINB | 0b00000001; // toggle bit 0, leave rest alone