Should I be able to assign a value of a named constant to a variable ?

Hi,

Should you be able to assign the value of a named constant to a variable of the same type? I'm finding the IDE won't compile if I do that - here's a scenario:

In the following snippet, by process of elimination by commenting and replacing I get an error compiling if fadeState is declared by a #define, or as a const int; however it works fine if it's defined as a plain old int.

// state variables & constants
<snip>
const int fadeState = 3;
<snip>
int mainEyesState = risingState;
<...and later, in loop()>
if(mainEyesState == onState) mainEyesState = fadeState;

This code fails to compile with "Error compiling" but the verbose output of the compile doesn't point me to anything meaningful (to me at least) as the issue. The bit that kills it is mainEyesState = fadeState at the end of the if. Comment that out, or replace it with mainEyesState = 3; and it's good to go.

I can get the whole thing to compile fine if I replace the state constants in this code with integers 0 through 5 so it's not a big deal, but was wondering if the inability to assign the value from a named constant of type const int to a variable of type int like this is prohibited in broader C/C++ and I've forgotten that...or if this is a bug that's worth reporting (I don't see it in the issues list already). I've not been able to find this limitation in my C/C++ references, so I'm presuming not but thought it best to check here.

As a further note, see that the declaration of variable mainEyesState compiles regardless of how I define risingState - as an int, const int or #define risingState 3 - which is an anomaly if you shouldn't be able to assign the value of a named constant to it. ie I can assign the value of a named constant to the integer typed variable, at time of declaration but not later.

Since I was bitten by #defines in IDE 1.0 I've slowly started to reintroduce them, but from this experience they're not entirely right yet either.

Hope this explanation makes sense. Is this a known bug, or am I trying to break a rule?

Cheers ! Geoff

This code fails to compile with "Error compiling" but the verbose output of the compile doesn't point me to anything meaningful (to me at least) as the issue.

Well, it might to us. Too bad you didn't show the output. Or all of the code.

Perhaps its those s in there. I'm pretty sure that they are not syntactically valid.

was wondering if the inability to assign the value from a named constant of type const int to a variable of type int like this is prohibited in broader C/C++

No, it isn't.

const int a = 3;
int b = 19;
#define c 24

void setup()
{
  int d = a;
  int e = b;
  int f = c;
}

void loop()
{
}

Compiles with no errors.

This code fails to compile with "Error compiling" but the verbose output of the compile doesn't point me to anything meaningful (to me at least) as the issue.

Well you should at least lets have a shot at trying to see what the actual error message is trying to tell you. Also without a more complete sketch it's hard to see the context of the error, for instance could this be a simple 'scope' error? Don't know because not enough code to tell where and when the various statements are made in relationship to each other.

Lefty

Hi Paul

Thanks for checking up on this. I've had a further finding. It will compile if the target is a Uno, fails if the target is the ATtiny85. Looks like I might be a step closer to finding what's up.

The code is an incomplete project started this evening to run some LEDs on large hairy spider decorations:

#include <math.h>

/*
  ____        _     _           _____                
 / ___| _ __ (_) __| | ___ _ __| ____|   _  ___  ___ 
 \___ \| '_ \| |/ _` |/ _ \ '__|  _|| | | |/ _ \/ __|
  ___) | |_) | | (_| |  __/ |  | |__| |_| |  __/\__ \
 |____/| .__/|_|\__,_|\___|_|  |_____\__, |\___||___/
       |_|                           |___/           
 
 */

// Halloween decoration based on ATtiny85

// pin definitions
const int noisePin = 4;                    // leg 3 adjacent to GND - for sound
const int mainEyes = 0;                    // leg 5 across from GND - for 5mm main eyes
const int sideEyes = 1;                    // leg 6 adjacent to D0 - for 3mm smaller eyes on side

// state variables & constants
// 0: off, 1: rising, 2: on, 3: fading
const int offState = 0;
const int risingState = 1;
const int onState = 2;
const int fadeState = 3;
int mainEyesState = risingState;
int sideEyesState = risingState;
boolean noiseState = false;

unsigned long mainEyesTimer = millis();
unsigned long sideEyesTimer = millis();
unsigned long noiseTimer = millis();

// ---------------------------------------------------------------------------------
// 
void setup() {
  pinMode(noisePin, OUTPUT);
  pinMode(mainEyes, OUTPUT);
  pinMode(sideEyes, OUTPUT);
  
  randomSeed(analogRead(A0));
}

// ---------------------------------------------------------------------------------
// 
void loop() {
  // test to see if any event needs to be triggered & change states
  if(millis() > mainEyesTimer) {
    if(mainEyesState == onState) mainEyesState = fadeState; 
//    if(mainEyesState == offState) mainEyesState = risingState;
//    if(sideEyesState != offState && sideEyesState != fadeState) sideEyesState = fadeState;
  }
  
  if(millis() >= sideEyesTimer) {
//    if(sideEyesState == onState) sideEyesState = fadeState;
//    if(sideEyesState == offState) {
//      if(mainEyesState != offState) sideEyesState = risingState;
//      else sideEyesTimer = mainEyesTimer;
//    } 
  }

  
  if(millis() > noiseTimer) {
    chirp();
    noiseTimer = millis() + random(1500, 30000);
  }
  
  fadeLEDs();
  
}

// ---------------------------------------------------------------------------------
// 
void fadeLEDs() {
  float val = (exp(sin((millis()-mainEyesTimer)/2000.0*PI)) - 0.36787944)*108.0;
  boolean complete = isAllDone(mainEyesState, val);
  if(complete && mainEyesState==fadeState) mainEyesState = offState;
  if(complete && mainEyesState==risingState) mainEyesState = onState;

  switch (mainEyesState) {
  case onState:
    digitalWrite(mainEyes, HIGH);
    mainEyesTimer = millis() + random(100, 10000);      // how long to stay fully bright
    break;

  case offState:
    digitalWrite(mainEyes,LOW);
    mainEyesTimer = millis() + random(1000, 10000);    // how long to stay off
    break;

  default:
    analogWrite(mainEyes, val);                        // else, continue fade
    break;
  }

  val = (exp(sin((millis()-sideEyesTimer)/2000.0*PI)) - 0.36787944)*108.0;
  complete = isAllDone(sideEyesState, val);
  if(complete && sideEyesState==fadeState) sideEyesState = offState;
  if(complete && sideEyesState==risingState) sideEyesState = onState;

  switch (sideEyesState) {
  case onState:
    digitalWrite(sideEyes, HIGH);
    sideEyesTimer = millis() + random(0, mainEyesTimer);  // side eyes will be off when main eyes are off
    break;

  case offState:
    digitalWrite(sideEyes,LOW);
    sideEyesTimer = millis() + random(1000, 10000);
    break;

  default:
    analogWrite(sideEyes, val);
    break;
  }
}

// ---------------------------------------------------------------------------------
// 
boolean isAllDone(int statetester, float valtester) {
  boolean result = (statetester == offState);                 // may as well end now
  result = result || ((statetester==fadeState) && (valtester < 1.0));
  result = result || ((statetester==risingState) && (valtester > 254));
  return result;
}

// ---------------------------------------------------------------------------------
// chirp the piezo speaker up to 3 times.
// this function is blocking, but doesn't take long
void chirp() {
  int times = random (1,4);                                  // 1 to 3 
  for(int i = 0; i < times; i++) {
    analogWrite(noisePin, random(25, 155));
    delay(random(100,500));
    analogWrite(noisePin, 0);                                // silence !
    if(i+1 < times) delay(random(100, 500));
  }
}

Because this post exceeds the forum limit - will put the output of the verbose compile in another post.

Cheers ! Geoff

this post exceeds the forum limit

But it fits into an attiny, including math.h ?

michael_x:

this post exceeds the forum limit

But it fits into an attiny, including math.h ?

The verbose compile message is what exceeds the limit. This sketch is small.

Update: just to confirm - when I change the state constants to just testing integer values, it compiles to Binary sketch size: 4,294 bytes (of a 8,192 byte maximum) but I'm prepared to drop the inclusion of math.h if this bloats out too far - I just like the way the LEDs fade in and out with that sinusoidal formula : ) Earlier tonight I had a test rig with the ATtiny85 and the LEDs setup with half running the opposing pulses to check the effect so this code has grown from that (working) point.

Because the verbose output is over 9500 chars, I ran a normal compile and the only output is this:

c:/program files (x86)/arduino-1.0.1/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr25/crttn85.o:(.init9+0x2): relocation truncated to fit: R_AVR_13_PCREL against symbol `exit' defined in .fini9 section in c:/program files (x86)/arduino-1.0.1/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/avr25\libgcc.a(_exit.o)

is this useful? Perhaps I can email/host a text file somewhere if not.

Thanks again for your thoughts on this,
Geoff

You can attach files to your post. Click on the 'Additional Options...' link under the text entry box.

This...

unsigned long mainEyesTimer = millis();
unsigned long sideEyesTimer = millis();
unsigned long noiseTimer = millis();

...is pointless. When the assignments are made, the millis hardware has not yet been initialized. The call to millis will always return zero.

strykeroz:
c:/program files (x86)/arduino-1.0.1/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr25/crttn85.o:(.init9+0x2): relocation truncated to fit: R_AVR_13_PCREL against symbol `exit' defined in .fini9 section in c:/program files (x86)/arduino-1.0.1/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/avr25\libgcc.a(_exit.o)

Bug in the linker...

strykeroz:
I just like the way the LEDs fade in and out with that sinusoidal formula : )

If that's all you need, you can generate Lissajous' figures iteratively.

Absolutely brilliant, as always guys!

Apologies for falling into the trap of not throwing everything at you initially. I'll jump into those instructions for sorting out the linker later this morning Coding Badly. It would appear un-commenting those extra lines of assignments pushed me over the trigger point for that bug.

Thanks again ! Geoff