Program and library work not on every PC

Hello everyone,

a friend an I have a awkward problem. We've written a library and a programm which uses the library. It works fine on my pc. But when we try it on his pc there is an error:

"Testprogramm_fuer_Module.ino: In function 'void loop()': Testprogramm_fuer_Module:31: error: 'class KKrfm70Class' has no member named 'Kanalwahl'"

I've got the same Windows version and the same Arduino version. Also there is a member called 'Kanalwahl'!!! I never saw somthing like this working on one pc but not on the other one. We tried a third pc - it worked again. We really don't know what is going on here.

Is there someone who has experienced this type of error? I would be very thankfull if someone could help us :)

Kind Regards, Kischy

Okay, there is new information. If we rename the library it suddenly works on his computer too. Now we are completely confused!

Kind Regards Kischy

if you want an explanation you could post the code involved ...

Here is the code of the program:

#include <KKrfm70.h>


/*Um das Programm auszuführen müssen folgende Funktionen public sein:
	//-----------eigentlich Private folgt-----------------
	void Gehe_RegBank(uint8_t bank); //Gehe in die angegebene Register Bank (Schreibe 0 für Bank 0, 1 für Bank 1)
	void SPI_Lese_Speicher(uint8_t reg, uint8_t *pSpeicher, uint8_t laenge);
	uint8_t SPI_Lese_Reg(uint8_t reg); //Lese Register
*/

KKrfm70Class rfmEmpf;

void setup()
{
  Serial.begin(115200);
  rfmEmpf.Initialisieren();
  rfmEmpf.WerdeEmpfaenger(3);
}


void loop()
{
  rfmEmpf.Gehe_RegBank(0);
  rfmEmpf.WerdeEmpfaenger(6);
  byte wert, werte[32];
  for(byte i=0;i<=90;i++)
  {
    Serial.print("Waehle Kanal Nr.");
    Serial.print(i);
    if(rfmEmpf.Kanalwahl(i))
    {
      Serial.println("\terfolgreich gewaehlt!");
    }
    else
    {
      Serial.println("\tKanal nicht verfuegbar!");
    }
  }
  
  
  for(byte i=0; i<=7;i++)
  {
    wert = rfmEmpf.SPI_Lese_Reg(R_REGISTER|i);
    Serial.print("Register: ");
    Serial.print(i,HEX);
    Serial.print("\tWert: ");
    Serial.println(wert,BIN);
  }
  for(byte i=17; i<=23;i++)
  {
    wert = rfmEmpf.SPI_Lese_Reg(R_REGISTER|i);
    Serial.print("Register: ");
    Serial.print(i,HEX);
    Serial.print("\tWert: ");
    Serial.println(wert,BIN);
  }
  for(byte i=28; i<=29;i++)
  {
    wert = rfmEmpf.SPI_Lese_Reg(R_REGISTER|i);
    Serial.print("Register: ");
    Serial.print(i,HEX);
    Serial.print("\tWert: ");
    Serial.println(wert,BIN);
  }

  //---Adressen--------
  wert=0;
  for(byte i=10; i<=11; i++)
  {    
    rfmEmpf.SPI_Lese_Speicher(R_REGISTER|i,&(werte[0]),5);
    Serial.print("Adresse Nr.");
    Serial.print(wert);
    Serial.print("\t");
    for(byte z=0; z<=4; z++)
    {
      Serial.print(werte[z],HEX);
      Serial.print(" ");
    }
    Serial.println();
    wert++;
  }
  for(byte i=12; i<=15;i++)
  {
    wert = rfmEmpf.SPI_Lese_Reg(R_REGISTER|i);
    Serial.print("Adresse Nr.");
    Serial.print(i,HEX);
    Serial.print("\t");
    Serial.println(wert,HEX);
  }


  rfmEmpf.Gehe_RegBank(1);
  Serial.println("Gehe zu Bank 1");
  wert = rfmEmpf.SPI_Lese_Reg(R_REGISTER|STATUS);
  wert = wert & 0x80;
  if(wert)
  {
    Serial.println("RegisterBank 1");
  }

  rfmEmpf.Gehe_RegBank(0);
  Serial.println("Gehe zu Bank 0");
  wert = rfmEmpf.SPI_Lese_Reg(R_REGISTER|STATUS);
  wert = wert & 0x80;
  if(wert==0)
  {
    Serial.println("RegisterBank 0");
  }
  for(int i=0; i<=5;i++)
  {    
    rfmEmpf.WerdeSender(i);
    Serial.print("Sendeadresse Nr.: ");
    Serial.print(i);
    Serial.print("\t");
    rfmEmpf.SPI_Lese_Speicher(R_REGISTER|TX_ADDR,&(werte[0]),5);
    for(byte z=0; z<=4; z++)
    {
      Serial.print(werte[z],HEX);
      Serial.print(" ");
    }
    Serial.println();
    
    Serial.print("RX_Adresse Nr.0: ");
    Serial.print("\t");
    rfmEmpf.SPI_Lese_Speicher(R_REGISTER|RX_ADDR_P0,&(werte[0]),5);
    for(byte z=0; z<=4; z++)
    {
      Serial.print(werte[z],HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
  delay(2500);
}

Here is the code if KKrfm70.h

#ifndef KKrfm70_h //Nichts soll zwei mal definiert werden
#define KKrfm70_h


#if defined(ARDUINO) && ARDUINO >= 100 
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
/*Dies testet welche Arduino Version verwendet wird (ältere Benutzen WProgram.h statt Arduino.h) und
füg den entsprechenden HEADER ein. Dies dient der Kompabilität mit anderen Systemen*/

#include <avr/pgmspace.h>
/*zu pgmspace.h: Erlaubt Variablen im Flash speicher abzulegen.
Siehe :
http://arduino.cc/de/Reference/PROGMEM,
http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html und
http://www.nongnu.org/avr-libc/user-manual/pgmspace.html vom 08.05.2014*/

#include <inttypes.h> 
/*Die Datentypen haben auf allen Systemen eine definierte Länge int8_t (int mit 8 Bit) uint8_t (unsigned int 8 Bit)
(weitere Informationen https://en.wikibooks.org/wiki/C_Programming/C_Reference/inttypes.h vom 08.05.2014) */

//------------------------PINBELEGUNG-------------------------------------------
/*SCK, MOSI und MISO ist reserviert durch Arduino. Die Pins können so selbst bestimmt werden ohne das wertvolle
Pins der Pulsweitenmodulation o.A. verwendet werden */
#define KKSCK	13 //Clock
#define KKMISO	12 //Master In Slave Out
#define KKMOSI	8 //Master Out Slave IN
#define CE	7 //Chip Select
#define CSN 4 //Slave Select (active: low)
#define IRQ 2 //Interrupt Pin (active: low)

#define MAX_PACKET_LENGTH 32 //Maximale Länge eines Packets sind 32 byte

//----------------------SPI Commands---------------------
#define R_REGISTER			0x00 //Lese Register 000AAAAA (AAAAA = 5 bit Register Karte)
#define W_REGISTER			0x20 //Schreibe Register 001AAAAA (AAAAA = 5 bit Register Karte)
#define R_RX_PAYLOAD		0x61 //Lese RX FIFO 
#define W_TX_PAYLOAD		0xA0 //Schreibe TX FIFO
#define FLUSH_TX			0xE1 //leere TX FIFO
#define FLUSH_RX			0xE2 //leere RX FIFO
#define REUSE_TX_PL			0xE3 //Für PTX - Wiederholtes senden der Packete
#define ACTIVATE			0x50 //Aktivieren verschiedener Kommandos und umschalten zw. den Registerbänken
#define R_RX_PL_WID			0x60 //Muss aktiviert werden (ACTIVATE-Command): Lese die Größe der Ladung in RX FIFO
#define W_ACK_PAYLOAD		0xA8 //Muss aktiviert werden (ACTIVATE-Command): Schreibe Ladung 10101PPP (PPP = Welcher Kanal PPP von 000 bis 101) - nur in RX Modus
#define W_TX_PAYLOAD_NO_ACK	0xB0 //Muss aktiviert werden (ACTIVATE-Command): In TX Modus: Schaltet AUTOACK (Bestätigung) für dieses Packet aus
#define NOP					0xFF //Nichts passiert - STATUS register kann gelesen werden

//-----------------------Register Adressen Bank 0----------
#define CONFIG			0x00 //Config
#define EN_AA			0x01 //Enable Auto Acknoledgment
#define EN_RXADDR		0x02 //Enable EX Piplines
#define SETUP_AW		0x03 //Setup Adresse
#define SETUP_RETR		0x04 //Setup Auto Retransmission
#define RF_CH			0x05 //Kanal!!!
#define RF_SETUP		0x06 //RF Setup (Leistung, Daten Rate, etc.)
#define STATUS			0x07 //Status Register
#define OBSERVE_TX		0x08 //Anzahl verlorene Packete, etc.
#define CD				0x09 //Carrier Detect
#define RX_ADDR_P0		0x0A //'RX address pipe0' register address
#define RX_ADDR_P1		0x0B //'RX address pipe1' register address
#define RX_ADDR_P2		0x0C //'RX address pipe2' register address
#define RX_ADDR_P3		0x0D //'RX address pipe3' register address
#define RX_ADDR_P4		0x0E //'RX address pipe4' register address
#define RX_ADDR_P5		0x0F //'RX address pipe5' register address
#define TX_ADDR			0x10 //'TX address' register address
#define RX_PW_P0        0x11 //'RX payload width, pipe0' register address
#define RX_PW_P1        0x12 //'RX payload width, pipe1' register address
#define RX_PW_P2        0x13 //'RX payload width, pipe2' register address
#define RX_PW_P3        0x14 //'RX payload width, pipe3' register address
#define RX_PW_P4        0x15 //'RX payload width, pipe4' register address
#define RX_PW_P5        0x16 //'RX payload width, pipe5' register address
#define FIFO_STATUS     0x17 //'FIFO Status Register' register address
#define DYNPD			0x1C //Dynamische Packetlänge
#define FEATURE			0x1D //Dynamische Packetlänge, ACK, etc.


//---------------------------FIFO STATUS------------------------------------
#define FIFO_STATUS_TX_VOLL 	0x20
#define FIFO_STATUS_TX_LEER 	0x10
#define FIFO_STATUS_RX_VOLL 	0x02
#define FIFO_STATUS_RX_LEER 	0x01

//---------------------------STATUS REGISTER Status--------------------------
#define STATUS_RX_DR 	0x40
#define STATUS_TX_DS 	0x20
#define STATUS_MAX_RT 	0x10
#define STATUS_TX_FULL 	0x01



class KKrfm70Class
{
private:
	uint8_t status; //Speichert den Status des STATUS register
	uint8_t Lese_InterruptPin(); //Gibt den Wert des IRQ zurück! (Um schnell zwischen Inverser und normaler Logik wechseln zu können)
	uint8_t SPI_LS(uint8_t wert); //Lese schreibe 8 bit
	void SPI_Schreibe_Speicher(uint8_t reg, uint8_t *pSpeicher, uint8_t laenge);

public:
	void SPI_Schreibe_Reg(uint8_t reg, uint8_t wert); //Schreibe ein Register
	void Initialisieren(); //Funktion schreibt alle Register auf Standardwerte und setzt die PINS
	void WerdeSender(uint8_t datenleitung); //Werde Sender auf Datenleitung datenleitung
	void WerdeEmpfaenger(uint8_t anz_leitungen); //Werde Empfänger mit anz_leitungen datenleitungen (max 6)
	void Sende(uint8_t typ, uint8_t *pSpeicher, uint8_t laenge); //Senden
	uint8_t Selbsttest();
	uint8_t Empfange(uint8_t *pSpeicher); //Empfangen
	uint8_t TesteFeatureRegister(); //Testet die Werte im Feature Register
	uint8_t Kanalwahl(uint8_t kanal); //Kanalwahl 0 - 83 

	//------------Interrupts------------------
	uint8_t Daten_Gesendet_Interrupt();
	uint8_t Daten_Gesendet_Interrupt_Fail();
	uint8_t Daten_Empfangen_Interrupt();
	uint8_t Interrupt();
		//-----------eigentlich Private folgt-----------------
	void Gehe_RegBank(uint8_t bank); //Gehe in die angegebene Register Bank (Schreibe 0 für Bank 0, 1 für Bank 1)
	void SPI_Lese_Speicher(uint8_t reg, uint8_t *pSpeicher, uint8_t laenge);
	uint8_t SPI_Lese_Reg(uint8_t reg); //Lese Register

};
#endif

The code of the KKrfm70.cpp. It’s only an excerpt, because I only have 9500 characters.

#include "KKrfm70.h" //Offensichtlich, oder?

//---------------------Standard Werte Register Bank 0----------------------------
PROGMEM prog_uchar Reg_Bank0[19][2] = //PROGMEM = Programm speicher nutzen, prog_uchar (unsigned char), siehe pgmspace.h
{
	{0x00,0x0F}, //RX_DR/TX_DS/MAX_RT Interrupt an, CRC an (2byte), Power up, PRX
	{0x01,0x3F}, //Auto Acknowledgement für Datenleitungen 0,1,2,3,4 und 5
	{0x02,0x3F}, //Standard alle Datenleitungen an
	{0x03,0x03}, //Addresse ist 5 bytes lang
	{0x04,0xFF}, //Auto Retransmission delay (4000 us), Re-Transmit eingeschalten mit 15
	{0x05,0x00}, //Kanal 0 als Standard
	{0x06,0x3F}, //2 Mbps, 5 dBm, LNA: High gain
	{0x07,0x70}, //Clear RX_DR,TX_DS,MAX_RT
	{0x08,0x00},
	{0x09,0x00},
	{0x11,0x20}, //32 byte in RX Datenleitung 0
	{0x12,0x20}, //32 byte in RX Datenleitung 1
	{0x13,0x20}, //32 byte in RX Datenleitung 2
	{0x14,0x20}, //32 byte in RX Datenleitung 3
	{0x15,0x20}, //32 byte in RX Datenleitung 4
	{0x16,0x20}, //32 byte in RX Datenleitung 5
	{0x17,0x11}, //FIFO Status - manche müsse10001n 0 bekommen
	{0x1C,0x3F}, //dynamische Packetlänge für Datenleitungen 0,1,2,3,4 und 5 einschalten
	{0x1D,0x07}, //DPL an, Ladung mit Bestätigung an, schaltet WX_TX_PAYLIAD_NOACK Kommando an
};
//------------------------Standard Adressen Datenleitung 0-5------------------------
prog_uchar RX0_Adresse[] PROGMEM ={0xFF,0x43,0x17,0x10,0xAC};//Receive address data pipe 0
prog_uchar RX1_Adresse[] PROGMEM ={0x39,0x38,0x22,0xE4,0xD2};//Receive address data pipe 1
prog_uchar RX2_5_Adresse[] PROGMEM = { 0xB2, 0x2A, 0xAF, 0x6D };//Receive address data pipe 2,3,4,5 (Nur LSB byte Rest gleich wie bei RX1_Adresse)

//--------------------------Standard Werte Register Bank 1---------------------------
/*Adresse 0-8 MSB byte to LSB byte, MSB in jedem byte */
PROGMEM prog_uchar Reg_Bank1 [] [4] = 
{
{0x40, 0x4B, 0x01, 0xE2},// must write 0x404B01E2
{0xC0, 0x4B, 0x00, 0x00},// must write 0xC04B0000
{0xD0, 0xFC, 0x8C, 0x02},// must write 0xD0FC8C02
{0x99, 0x00, 0x39, 0x41},// must write 0x99003941
{0xD9, 0x9E, 0x86, 0x0B},// must write 0xD99E860B (High Power) oder 0xD99E8624 (Single carrier mode)
{0x24, 0x06, 0x7F, 0xA6},// must write 0x24067FA6
{0x00, 0x00, 0x00, 0x00},// reserved
{0x00, 0x00, 0x00, 0x00},// reserved
{0x00, 0x00, 0x00, 0x00},// reserved
{0x00, 0x00, 0x00, 0x00},// reserved
{0x00, 0x00, 0x00, 0x00},// reserved
{0x00, 0x00, 0x00, 0x00},// reserved
{0x00, 0x12, 0x73, 0x00},// must write 0x00731200
{0x36, 0xB4, 0x80, 0x00},// must write 0x0080B436
};

PROGMEM prog_uchar Reg_Bank1_14 [] = //Must write 0xFFFFFEF7CF208104082041 
{
	0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF
};

PROGMEM prog_uchar config_Sender [] = {0x0E}; //RX_DR/TX_DS/MAX_RT Interrupt an, CRC an (2byte), Power up, PTX


//----------------------------------Kanalwahl--------------------------------------
uint8_t KKrfm70Class::Kanalwahl(uint8_t kanal)
{
	if (kanal >= 0 && kanal <= 83)
	{
		SPI_Schreibe_Reg(W_REGISTER | RF_CH,kanal);
		if (SPI_Lese_Reg(R_REGISTER | RF_CH) == kanal)
		{
			return 1;
		}
	}
	return 0;
}