fastwrite function and digitalRead at the same tim

I want to send two high frequency pulse trains on two outputs. So I´m using the fastWrite macro.
I also want to use atleast one I/O line as input.

The following macro defines all 14 I/O-lines as outputs.
How it should be changed, so I would have possibility to inputs?

#define fastWrite(pin, state) ( pin < 8 ? (state ? PORTD |= 1 << pin : PORTD &= ~(1 << pin )) : (state ? PORTB |= 1 << (pin -8) : PORTB &= ~(1 << (pin -8) )))
// the macro sets or clears the appropriate bit in port D if the pin is less than 8 or port B if between 8 and 13

The following macro defines all 14 I/O-lines as outputs.

No it doesn’t - it simply writes the value of “state” to the appropriate port and pin. (PORTD if pin < 8, PORT B otherwise).
Nothing there that I can see to stop you using a pin as an input.

Oh, Really.

Then I must try again.

Thanks

Huh? The version of fastwrite() looks OK to me. What AWOL said was that it doesn’t actually change the pin directions or turn off PWM the way pinMode/digitalWrite would; it ASSUMES that the ports have already been configured as outputs. If in fact some pins have been set to be inputs with pinMode(), you can read from them just fine with digitalRead() (or direct port reads as well.) Isn’t that exactly what you wanted? Or are you looking for a definition of fastread() ?

The following is a different version of fastwrite() that I think is a bit clearer. It SHOULD work for any of the normal pin numbers, and it’s easily modifiable for different pin mappings.

It LOOKS like really verbose source code, but as long as both val and pin are constants, it should compile to a single instruction by the time the compiler is done optimizing it.

#define fastwrite(pin, val) if (val) switch (pin) {     \
    case 0: PORTD |= 1<<0; break;       \
    case 1: PORTD |= 1<<1; break;       \
    case 2: PORTD |= 1<<2; break;       \
    case 3: PORTD |= 1<<3; break;       \
    case 4: PORTD |= 1<<4; break;       \
    case 5: PORTD |= 1<<5; break;       \
    case 6: PORTD |= 1<<6; break;       \
    case 7: PORTD |= 1<<7; break;       \
    case 8: PORTB |= 1<<0; break;       \
    case 9: PORTB |= 1<<1; break;       \
    case 10: PORTB |= 1<<2; break;      \
    case 11: PORTB |= 1<<3; break;      \
    case 12: PORTB |= 1<<4; break;      \
    case 13: PORTB |= 1<<5; break;      \
    } else switch (pin) {               \
    case 0: PORTD &= ~(1<<0); break;    \
    case 1: PORTD &= ~(1<<1); break;    \
    case 2: PORTD &= ~(1<<2); break;    \
    case 3: PORTD &= ~(1<<3); break;    \
    case 4: PORTD &= ~(1<<4); break;    \
    case 5: PORTD &= ~(1<<5); break;    \
    case 6: PORTD &= ~(1<<6); break;    \
    case 7: PORTD &= ~(1<<7); break;    \
    case 8: PORTB &= ~(1<<0); break;    \
    case 9: PORTB &= ~(1<<1); break;    \
    case 10: PORTB &= ~(1<<2); break;   \
    case 11: PORTB &= ~(1<<3); break;   \
    case 12: PORTB &= ~(1<<4); break;   \
    case 13: PORTB &= ~(1<<5); break;   \
    }

This has only been tested with some trivial Blink-like examples. It may have bugs.

I much prefer macros to use ugly backslash continuation characters in their definitions than to use “magic” C constructs to force everything onto a single line of C code. Of course the macro you have now could be rewritten to use “if” instead of “?” and generate somewhat better code than the above for non-constant arguments, at the expense of having less general pin number mapping capabilities.

I much prefer macros to use ugly backslash continuation characters in their definitions than to use "magic" C constructs

The C ternary operator is no more magical than the C case statement, but I do agree that version with the case statement is easier to read.

BTW, I get a java stack overflow error compiling your case version of fastwrite in IDE version 0016.

The C ternary operator is no more magical than the C case statement

agreed, but it less “standard” in a cross-language sense. If you’re familiar with some other language, “?:” statements are more likely to look like line noise than something with keywords…

I get a java stack overflow error compiling your case version of fastwrite in IDE version 0016.

Odd. I don’t get the overflow, but I also can’t get it to compile if I put the macro definition inside the .pde file itself. I don’t think the Arduino pre-processing likes line-continuation characters! (It works fine with the macro in a separate .h file.)

#include "fastwrite.h"

#define ledPin 12                // LED connected to digital pin 13
#define ledPin2 13

void setup()                    // run once, when the sketch starts
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  pinMode(ledPin2, OUTPUT);
}

void loop()                     // run over and over again
{
  fastwrite(ledPin2, HIGH);
  fastwrite(ledPin, HIGH);   // sets the LED on
  delay(50);                  // waits for a second
  fastwrite(ledPin, LOW);    // sets the LED off
  delay(100);                  // waits for a second
  fastwrite(ledPin, HIGH);
  delay(50);
  fastwrite(ledPin, LOW);
  fastwrite(ledPin2, LOW);
  delay(850);
}

fastwrite.h:

#define fastwrite(pin, val) if (val) switch (pin) {      \
    case 0: PORTD |= 1<<0; break;      \
    case 1: PORTD |= 1<<1; break;      \
    case 2: PORTD |= 1<<2; break;      \
    case 3: PORTD |= 1<<3; break;      \
    case 4: PORTD |= 1<<4; break;      \
    case 5: PORTD |= 1<<5; break;      \
    case 6: PORTD |= 1<<6; break;      \
    case 7: PORTD |= 1<<7; break;      \
    case 8: PORTB |= 1<<0; break;      \
    case 9: PORTB |= 1<<1; break;      \
    case 10: PORTB |= 1<<2; break;      \
    case 11: PORTB |= 1<<3; break;      \
    case 12: PORTB |= 1<<4; break;      \
    case 13: PORTB |= 1<<5; break;      \
    } else switch (pin) {               \
    case 0: PORTD &= ~(1<<0); break;      \
    case 1: PORTD &= ~(1<<1); break;      \
    case 2: PORTD &= ~(1<<2); break;      \
    case 3: PORTD &= ~(1<<3); break;      \
    case 4: PORTD &= ~(1<<4); break;      \
    case 5: PORTD &= ~(1<<5); break;      \
    case 6: PORTD &= ~(1<<6); break;      \
    case 7: PORTD &= ~(1<<7); break;      \
    case 8: PORTB &= ~(1<<0); break;      \
    case 9: PORTB &= ~(1<<1); break;      \
    case 10: PORTB &= ~(1<<2); break;      \
    case 11: PORTB &= ~(1<<3); break;      \
    case 12: PORTB &= ~(1<<4); break;      \
    case 13: PORTB &= ~(1<<5); break;      \
    }

merged into a single PDE (and with some other modifications to attempt a fix), I end up getting a .cpp file that has:

#define ledPin 12                // LED connected to digital pin 13
#define ledPin2 13

#include "WProgram.h"
void setup();
else switch (_pin);
void loop();
void setup()                    // run once, when the sketch starts
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  pinMode(ledPin2, OUTPUT);
}

#define fastwrite(_pin, _val) if (_val) switch (_pin) { \

agreed, but it less “standard” in a cross-language sense. If you’re familiar with some other language, “?:” statements are more likely to look like line noise than something with keywords…

The use of #define macros are also cross-language unfriendly so neither version is easily used in another language. But I do agree the ternary version is more cryptic so the case version is the better choice.

Thanks for clarifying the need for the external H file, that works nicely.

Edit: I was curious what the effect would be if these macros were inadvertently used with variables instead of constants. The case version expands to more 150 more bytes of code than the ternary version for each call.