Multi-File/Tab Sketch is not compiling...

Hi,
I’m working with an Arduino Duemilanove to control a heat element (digital driven SCR w/cross-zero detection for a 4000W resistive load over 127 VAC@60Hz). After some issues, hardware is working properly but now I’m facing a new issue. For characterization and calibration purposes it is necessary to inject a signal (from signal generator) to arduino and then proportional pulses are generated for trigger the SCR at appropriate times.

For zero-cross detection, external interrupt was used. Working.
For ADC calibration a vccRead function was used.http://hacking.majenko.co.uk/making-accurate-adc-readings-on-arduino. Working.

For timing, inside the interrupt function delayMicroseconds it is used to calculate SCR firing angle with pretty good performance.
In loop(), generator and thermocouple signals are sampled and timing is done by delay() function with no good accuracy. So this is where I get into troubles.

I decide to use an alternative method for control the timing for the sampling process. Using micros() and millis() functions, the problem could work around. It was when I found this code http://www.uchobby.com/index.php/2012/01/21/replacing-delay-in-arduino-sketches-istime-to-the-rescue/. Code looks good, but when I try to compile I got several error messages:

misTiempos.c: In function 'isMyTime':
misTiempos.c:13: warning: this decimal constant is unsigned only in ISO C90
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\malloc.c:67: warning: initialization makes pointer from integer without a cast
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\HardwareSerial.cpp: In function 'void store_char(unsigned char, ring_buffer*)':
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\HardwareSerial.cpp:98: warning: comparison between signed and unsigned integer expressions
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\HardwareSerial.cpp: In function 'void __vector_18()':
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\HardwareSerial.cpp:132: warning: unused variable 'c'
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\HardwareSerial.cpp: In member function 'void HardwareSerial::begin(long unsigned int, byte)':
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\HardwareSerial.cpp:379: warning: unused variable 'current_config'
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\HardwareSerial.cpp: In member function 'virtual size_t HardwareSerial::write(uint8_t)':
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\HardwareSerial.cpp:478: warning: comparison between signed and unsigned integer expressions
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\Print.cpp: In member function 'size_t Print::print(const __FlashStringHelper*)':
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\Print.cpp:44: warning: '__progmem__' attribute ignored
C:\Program Files (x86)\arduino-1.0.4\hardware\arduino\cores\arduino\Tone.cpp:119: warning: only initialized variables can be placed into program memory area
[color=red]ovenCharacterization_002.cpp.o: In function `setup':
C:\Program Files (x86)\arduino-1.0.4/ovenCharacterization_002.ino:23: undefined reference to `mireadVcc()'[/color]

All compilation message option enabled. Only red marked its the most important.

the code:
ovenCharacterization_002

#include "misADCfun.h"
#include "misTiempos.h"

#define TERMOPAR_PIN 0 // Entrada del termopar
#define GEN 2 // Entrada del Generador
#define ANALOG_VOLTAGE_REFERENCE 5

volatile int G, T, Taux, Tauxsum=0, index=0 ;

void setup()
{

  Serial.begin(115200);
  Serial.println( mireadVcc(), DEC );
 G = analogRead(GEN);
  T = analogRead(TERMOPAR_PIN);

  pinMode(3, INPUT);
  pinMode(5, OUTPUT);
  attachInterrupt(1, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above

}

unsigned long flashTimeMark=0;  //a millisecond time stamp used by the IsTime() function. initialize to 0
unsigned long flashTimeInterval=125;  //How many milliseconds we want for the flash cycle. 1000mS is 1 second.

void loop()
{
  G = analogRead(GEN);
  Taux = analogRead(TERMOPAR_PIN);  
  if (index==3) 
  {
    Tauxsum += Taux;
    T = Tauxsum/4;
    Tauxsum = 0;
    index = 0;

   Serial.print(G);
    Serial.print(",");
    Serial.println(T);
  }
  else
  {
    Tauxsum += Taux;
    index++;
  }
  while( isMyTime(&flashTimeMark,flashTimeInterval) );
  //delay(125); 
}
void zero_crosss_int()  
{ 
  delayMicroseconds(250); 
  delayMicroseconds(8003-(G*7.81)); 
  PORTD &= ~_BV(5); 
  delayMicroseconds(4); 
  PORTD |= _BV(5); 
}

misADVfun.c

#include "misADCfun.h"

long mireadVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;
}

misTiempos.c

#include "misTiempos.h"

#define TIMECTL_MAXTICKS  4294967295L
#define TIMECTL_INIT      0

int isMyTime(unsigned long *timeMark, unsigned long timeInterval){
  unsigned long timeCurrent;
  unsigned long timeElapsed;
  int result=false;
  
  timeCurrent=millis();
  if(timeCurrent<*timeMark) {  //Rollover detected
    timeElapsed=(TIMECTL_MAXTICKS-*timeMark)+timeCurrent;  //elapsed=all the ticks to overflow + all the ticks since overflow
  }
  else {
    timeElapsed=timeCurrent-*timeMark;  
  }

  if(timeElapsed>=timeInterval) {
    *timeMark=timeCurrent;
    result=true;
  }
  return(result);  
}

misADCfun.h

#ifdef __cplusplus
extern "C" 
#endif

#include <Arduino.h>

long mireadVcc();

misTiempos.h

#ifdef __cplusplus
extern "C" 
#endif

#include <Arduino.h>

int isMyTime(unsigned long *timeMark, unsigned long timeInterval);

All files are in the same sketch folder, an interesting effect when change order of includes in main sketch (but not solve the problem).
My arduino is 1.0.4.

Thanks for reading, hope an answer.

Eccker

Hi,
you seem to use a custom build process, and as you probably know the error you get is a linker error. The compiler is happy because it finds the function declaration in the .h file, but the linker wants the definition from a .c (properly .o) file. The most likely cause is that the .c files were not compiled [or linked] because you didn’t include them in your makefile* (or whatever you use for the custom build process). If this doesn’t help, please post also a log of the compiler/linker commands and/or your makefile.

[edit] * in both the compiler and linker sections.

This code:

#ifdef __cplusplus
extern "C" 
#endif

Should include a '{', and there should be a matching } at the end of the header.

This code ... Should include a '{', and there should be a matching } at the end of the header.

And, the #include statement should NOT be in the extern C block.

Great replies,

As spatula points out, compilation error was due to a lack of linking .c files. However, the problem was not in the build process script but instead as PaulS mentioned,

Should include a ‘{’, and there should be a matching } at the end of the header.

is necessary in each header file for C code, and also as PeterH said,

the #include statement should NOT be in the extern C block.

Properly closing the block in each .h file and making sure #include statement is out of block resolve my issue. Thanks a lot.

eccker