#include // I2C #define EXT_EE_ADDR 0x50 // I2C address of 1. external eeprom new 15.05.2025 #define EXT_EE_SIZE 32768 // Max address for 32k-eeprom 22.05.2025 #define EXT_EE_LIMIT 30 // Write buffer limit #define EXT_EE_PAGE 64 // Page size #define EXT_EE_MELODY 0 // Melody data start address in external eeprom #define EXT_EE_CALENDAR 5000 // Calendar data start address in external eeprom 02.06.2025 #define EXT_EE_TEST1 12000 // Test-data 1 start address in external eeprom ++++ 18.06.2025 10000 -> 12000 #define EXT_EE_TEST2 17000 // Test-data 2 start address in external eeprom ++++ 15000 -> 17000 #define EXT_EE_TEST3 22000 // Test-data 3 start address in external eeprom ++++ 20000 -> 22000 int receive_timer = 0; // Receive timer byte serbuf = 0; // Maximum value of the serial buffer byte xon = 0; // Number of xoff while receiving byte xoff = 0; // Number of xoff while receiving static bool rx_flag = 0; // Flag for XOFF status char test_addr[3] = {'\0'}; // Buffer byte Ser_Arr[31]; // Array for page write byte cur_byte = 0; // Array index of bytes received !!!! 19.06.2025 unsigned int receive_addr=EXT_EE_TEST1; // Receive address int rx_err = 0; // Receive error counter static bool rx_run; // Receive ongoing int cnt = 0; // Offset for receiving data byte for_count = 0; // DEBUG! count for loop repeat int ram_idx = 0; // DEBUG! index for storing to ram int log_idx = 0; // DEBUG! index for logging int data_idx = 0; // DEBUG! index for data byte rx_test[256] = {}; // DEBUG! buffer byte log_data[200]; // DEBUG! data sent to page write byte log_status[200]; // DEBUG! i2c-status byte log_bytes[200]; // DEBUG! log bytes byte log_val[200]; // DEBUG! log value int log_cnt[200]; // DEBUG! log cnt-value void setup() { // put your setup code here, to run once: Wire.begin(); Wire.setClock(100000); // Set I2C clock frequency Serial.begin(9600); // opens serial port, sets data rate to 96000 bps Serial.println(); // CR LF Serial.println(F("Setup fertig")); // Message Serial.println(); Serial.println(F("I2C-Scanner: ")); // I2C-Scanner bool error = true; // Flag for I2C-error I2C-Scan int addressFound = false; // Flag for valid adress for(int i2ad=1; i2ad<0x7F; i2ad++){ // I2C adress-range Wire.beginTransmission(i2ad); // Start transmission error = Wire.endTransmission(); // Check status if(error == 0){ // No error addressFound ++; // Adress found Serial.print(F("0x")); // Preambel Serial.print(i2ad,HEX); // Address Serial.print(F(" "));}} // Space Serial.println(); // CR LF if(!addressFound){ // No adress Serial.print(F("No I2C Address found "));}// Message else{Serial.print(addressFound); // Number Serial.print(F(" Addresses found "));} // Text Serial.println(); // CR LF Serial.println(); // CR LF Serial.println(F("Setup Ende")); // Message Serial.println(); // CR LF Serial.println(F("Bitte Testdaten 00-9F senden")); // Message } void loop() { // put your main code here, to run repeatedly: test_data_rec_(); // Receive serial data } void test_data_rec_(){ // External eeprom data receive - menu17 - page write unsigned int addr = receive_addr; int rx=0; // Set receive address for external eeprom byte hi, lo, val; char nibble; // High nibble, low nibble and value byte bytes; byte x; // Bytes left in page, no. of bytes processed by for-loop while ((Serial.available() >= 2) || // As long as data are available (receive_timer >0)) { // Or receive timeout is running if (!rx_run){receive_timer=299;rx_run=1;} // Set receive timeout counter (only once) ! if (receive_timer){receive_timer--;} // Decrease receive timeout counter delay(10); for_count++; // DEBUG! How often is the for loop exectuted? x = Serial.available(); // Store total number of char received (max. 64) //cur_byte = 0; for (int i=0; i < x/2; i++){ // Process total number of bytes (=2 nibbles) received 2 4 6 8 byte y = Serial.available(); // Current buffer state = no of char! if (y > serbuf){serbuf=y;} // Buffer max size nibble = text2hex(Serial.read()); // read and convert 1. char = high nibble hi = nibble; // High nibble nibble = text2hex(Serial.read()); // read and convert 2. char = low nibble lo = nibble; // Low nibble val = hi<<4 | lo; // Combine hi + low = value rx_test[ram_idx] = val; // DEBUG! store to RAM ram_idx++; // DEBUG! index for ram //flow_control(Serial.available()); // Flow-control (current buffer state) - not used! bytes=bytes_in_page(addr+cnt); // Determinate max. number allowed in this page if ((cur_byte < x/2) && // Not all data processed | -> collect data (cur_byte < bytes)){ // Below buffer or page-write border | Ser_Arr[cur_byte]= val; // Add data to page-write buffer | //debug_collect(); // DEBUG! show collecting state | cur_byte++; // Next index | } if ((cur_byte == x/2) || // current count = received bytes | -> page write (cur_byte == bytes)){ // Buffer or page-write border reached | page_write(addr+cnt,cur_byte); // Perform page-write to ext ee | of page write cnt=cnt+cur_byte; // Increase address by bytes added | -> prepare next packet cur_byte = 0; // Clear index | } } } if(rx_run){ // DEBUG! rx executed before Serial.print(F("Bytes left ")); // DEBUG! Message Serial.print(x); // DEBUG! x = bytes processed by for-loop Serial.print(F(" Max. Buffer ")); // DEBUG! Message Serial.print(serbuf); // DEBUG! max. buffer state Serial.print(F(" cnt ")); // DEBUG! Message Serial.print(cnt); // DEBUG! cnt if (cnt!=160){ // Works only for exactly 160 bytes of data Serial.print(F(" ERROR 160 Bytes expected"));} else {Serial.print(F(" OK "));} // OK Serial.println(); // CR LF ext_ee_test1_read(); // Print eeprom content ext_ee_test3_read(); // Print RAM-content rx_run=0; // Clear rx run flag ram_idx = 0; // Reset receive ram index cnt = 0; // Clear counter for next try ext_ee_clear(); // Erase EEPROM } } char text2hex(char myChar){ // Convert text to hex byte y; // if (myChar >= '0' && myChar <= '9') { // 0-9 return myChar - '0';} // else if (myChar >= 'A' && myChar <= 'F') { // A-F return myChar - 'A' + 10;} // else {rx_err++;} // Blank + rex_error old: return 0; } byte bytes_in_page(unsigned int addr){ // Number of bytes left in page if (addr < EXT_EE_SIZE){ // Address is valid int page = addr / EXT_EE_PAGE; // Current page int border = (page + 1) * EXT_EE_PAGE; // Next page address = border int bytes = border - addr; // Number of bytes total int pakets = (bytes / EXT_EE_LIMIT)+1; // Number pf pakets int rest = bytes; int count = 0; // Rest of bytes if (rest >= EXT_EE_LIMIT){ // Enough space for 30 bytes count = EXT_EE_LIMIT;} // else if (rest < EXT_EE_LIMIT){ // Less space than 30 bytes count = rest;} // return count; // Number of bytes } else{ Serial.print(F("Illegal Address"));} } void write_ext_eeprom(unsigned int addr, byte byteToWrite){ if (addr < EXT_EE_SIZE){ // Address is valid Wire.beginTransmission(EXT_EE_ADDR); // Start transmission Address of external eeprom Wire.write((byte)(addr>>8)); // Address high Wire.write((byte)(addr&0xFF)); // Address low Wire.write(byteToWrite); // Write byte Wire.endTransmission(); // End transmission delay(5);}} // important! byte page_write(unsigned int addr, unsigned int number){ Wire.beginTransmission(EXT_EE_ADDR); // Start transmission to I2C address Wire.write((byte)(addr>>8)); // Address eeprom high Wire.write((byte)(addr&0xFF)); // Address eeprom low for(unsigned int i=0; i>8)); // Address high Wire.write((byte)(addr&0xFF)); // Address low Wire.endTransmission(); // End transmission Wire.requestFrom(EXT_EE_ADDR, 1); // Allow multiple requests byteToRead = Wire.read(); // Read byte return byteToRead; // Return value } } void ext_ee_test1_read(){ // Read test data 1 - menu 18 key 5 - settings Serial.println(); // CR LF Serial.print(F("EEPROM Settings"));Serial.println(); // Test 1 print_data(EXT_EE_TEST1,0); // Ext eeprom 1 = page write } void ext_ee_test3_read(){ // Read test data 3 - menu 18 key 7 - melody Serial.println(); // CR LF Serial.print(F("RAM rx_test"));Serial.println(); // Test 3 DEBUG! from test-ram print_data(EXT_EE_TEST3,1); // Ext eeprom 3 = page write } void print_data(unsigned addr,byte mode){ // Print data for (unsigned int x=0; x < 256; x++){ // Count 512 values byte y = 0; if(!mode){y=read_ext_eeprom(addr+x);} // Data from ext eeprom else{y=rx_test[x];} // Data from ram if(y<0x10){Serial.print("0");} // Add a leading 0 Serial.print(y,HEX); // Print char Serial.print(" "); // Add a blank // Serial.print(x); // Debug Address // Serial.print(" "); // Add a blank y = x & 0x000F; // Mask low nibble // Serial.print(y,HEX); // Debug // Serial.print(" "); // Add a blank if(y == 15){Serial.print(" "); // Blank Serial.print(x+1); // Counter Serial.println();}} // CR LF after each 16 bytes Serial.println(); // CR LF } void ext_ee_clear(){ // Clear eeprom - menu 18 key 9 Serial.print(F("EEPROM clear")); // Clear EEPROM at receive_addr Serial.println(); // for (unsigned int x=0; x < 256; x++){ // Counter write_ext_eeprom(receive_addr+x,0xFF); // Clear eeprom from external address x } }