what could this error message be telling me?

In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/wiring_digital.c:27:
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/digital_write.h:137: error: redefinition of 'atomicWrite'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/digital_write.h:137: error: previous definition of 'atomicWrite' was here

so its saying I redefined the function on the same line ?!?

#ifndef atomicWrite  //I surrounded the definition with this after I first saw the error
static inline void atomicWrite( uint8_t* address, uint8_t p, uint8_t v) {
      if ((int)address < 0x20)     bitWrite(*address, __digitalPinToBit(p),v);
      else  {
            uint8_t register saveSreg = SREG;     
            cli();                                  
            bitWrite(*address, __digitalPinToBit(p), v);  
            SREG=saveSreg;
      }
}
#endif

#define digitalWrite(P, V) \
do {                       \
if (__builtin_constant_p(P) && __builtin_constant_p(V))   atomicWrite((uint8_t*) digitalPinToPortReg(P),P,V); \
else  __digitalWrite((P), (V));         \
}while (0)

#define pinMode(P, V) \
do {if (__builtin_constant_p(P) && __builtin_constant_p(V)) atomicWrite((uint8_t*) digitalPinToDDRReg(P),P,V); \
__pinMode((P), (V)); \
} while (0)


#if !defined(stopAnalogWrite)
#define stopAnalogWrite(P) \
do {if (__builtin_constant_p(P) ) { \
if (__digitalPinToTimer(P)) \
bitClear(*__digitalPinToTimer(P), __digitalPinToTimerBit(P)); \
} else {  \
turnOffPWM((P)); \
}} while (0)
#endif            


#define digitalRead(P) ( (int) __digitalReadFast2__((P)) )
#define __digitalReadFast2__(P) \
(__builtin_constant_p(P) ) ? ( \
( bitRead(*digitalPinToPINReg(P), __digitalPinToBit(P))) ) : \
__digitalRead((P))

sometimes I feel like compiler will never really be my friend.

it occurred to me while raking leaves, knowing that what I had done just before this error occurred was to split this code out of wiring.h (it had become more than 1/2 of what was there and the files in the core are pretty small) and a bit of change to wiring_digital.c , that perhaps I'd left an unbalanced #if of some sort in one of the 3 files. That does not seem to be the case; #error messages appended to each of these files does generate the expected error message.

You create a second function with the name atomicWrite, which is bad ane confuses the compiler. Change it to nuclearWrite.

Korman

I changed the name

In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/wiring_digital.c:27:
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/digital_write.h:137: error: redefinition of '_atomic_Write_'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/digital_write.h:137: error: previous definition of '_atomic_Write_' was here

That error went away when I deleted a second #include that was including the file. don’t know why the #ifndef wasn’t protecting me, but its gone.

jjraines,

The #ifndef does not check whether a function has not been defined. It can only check whether a name has not been #defined.

The usual way to use it is:

#ifndef _thing
#define _thing
void thing(void)
{
// etc
}
#endif     // #ifndef _thing

Note that you have to #define _thing inside the #ifndef block. This keeps the contents of the block from being inserted more than once, even if the file in which it resides is included more than once. It's generally a good practice to use a unique name (for example, by putting an underscore in front of a function name) to avoid unintended macro substitution.

Regards,

-Mike

Seems like a good tip , definitely something I didn’t know and wouldn’t have suspected. But

#ifndef Atomic_Write_H
#define Atomic_Write_H
inline void _atomic_Write_( uint8_t* address, uint8_t p, uint8_t v) {
      if ((int)address < 0x20)     bitWrite(*address, __digitalPinToBit(p),v);
      else  {
            uint8_t register saveSreg = SREG;     
            cli();                                  
            bitWrite(*address, __digitalPinToBit(p), v);  
            SREG=saveSreg;
      }
}
#endif

still leaves me with similar errors; complaint of multiple definition on the same line.

core.a(wiring_analog.c.o): In function `_atomic_Write_':
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/digital_write.h:142: multiple definition of `_atomic_Write_'
core.a(wiring.c.o):/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/digital_write.h:142: first defined here
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld: Disabling relaxation: it will not work with multiple definitions
core.a(wiring_digital.c.o): In function `_atomic_Write_':
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/digital_write.h:142: multiple definition of `_atomic_Write_'
core.a(wiring.c.o):/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/digital_write.h:142: first defined here
core.a(pins_arduino.c.o): In function `_atomic_Write_':
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/digital_write.h:142: multiple definition of `_atomic_Write_'
core.a(wiring.c.o):/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/digital_write.h:142: first defined here

This is different in that it labels the line always as ‘first definition’ whereas before it said one time it was a ‘redefinition’ and the other was a ‘previous’ definition. So maybe its actually a different error.

As a test ... move the function body into a cpp file. You will have to add the appropriate #include lines to the cpp file. Does that make a difference?

I rebuilt Arduino from a fresh download. Seemed like I’ve been seeing too many weird errors. That didn’t help.

I tried moving

#ifndef Atomic_Write_H
#define Atomic_Write_H
inline void _atomic_Write_( uint8_t* address, uint8_t p, uint8_t v) {
      if ((int)address < 0x20)     bitWrite(*address, __digitalPinToBit(p),v);
      else  {
            uint8_t register saveSreg = SREG;     
            cli();                                  
            bitWrite(*address, __digitalPinToBit(p), v);  
            SREG=saveSreg;
      }
}
#endif

#define digitalWrite(P, V) \
do {                       \
if (__builtin_constant_p(P) && __builtin_constant_p(V))   _atomic_Write_((uint8_t*) digitalPinToPortReg(P),P,V); \
else  __digitalWrite((P), (V));         \
}while (0)

#define pinMode(P, V) \
do {if (__builtin_constant_p(P) && __builtin_constant_p(V)) _atomic_Write_((uint8_t*) digitalPinToDDRReg(P),P,V); \
__pinMode((P), (V)); \
} while (0)


#if !defined(stopAnalogWrite)
#define stopAnalogWrite(P) \
do {if (__builtin_constant_p(P) ) { \
if (__digitalPinToTimer(P)) \
bitClear(*__digitalPinToTimer(P), __digitalPinToTimerBit(P)); \
} else {  \
turnOffPWM((P)); \
}} while (0)
#endif            


#define digitalRead(P) ( (int) __digitalReadFast2__((P)) )
#define __digitalReadFast2__(P) \
(__builtin_constant_p(P) ) ? ( \
( bitRead(*digitalPinToPINReg(P), __digitalPinToBit(P))) ) : \
__digitalRead((P)) 


void __pinMode(uint8_t pin, uint8_t mode)
{
      uint8_t bit = digitalPinToBitMask(pin);
      uint8_t port = digitalPinToPort(pin);
      volatile uint8_t *reg;

      if (port == NOT_A_PIN) return;

      // JWS: can I let the optimizer do this?
      reg = portModeRegister(port);

      if (mode == INPUT) { 
            uint8_t oldSREG = SREG;
                cli();
            *reg &= ~bit;
            SREG = oldSREG;
      } else {
            uint8_t oldSREG = SREG;
                cli();
            *reg |= bit;
            SREG = oldSREG;
      }
}

from the new digital_write.h file to wiring_digital.c

the problem is that wiring.h used to have declarations of digitalWrite, pinMode and digitalRead and here they are macros. so other files include wiring.h and then complain that pinMode etc aren’t there. I will get this figured out in the morning. It is actually getting clearer how things need to divide up, I think.

I will tackle it in the morning when I am fresher.

Mike's comment helps me enormously. Somehow I had not fully internalized that the preproceessor is a completely separate 'language' and that it considers those lines that start with # (the the continuation lines following # lines that end in '\') to be 'language' and everything else to be 'data'. It explains a lot of what I'd been viewing as weirdness the past 8 days . It gives me a greater respect for the value of 'camel case', which is widely ignored in the code base. 'Camel case' clarifies the issue Mike pointed out.

In places I was using #ifdef backwards from what I should have, picking exactly the wrong symbols.

It gives me hope that I will go back to thinking of the compiler as my friend.

Thanks again!