diff --git a/CHANGELOG b/CHANGELOG index 740bff1..6056417 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,32 @@ CHANGELOG: +Version 0.1.9: + + Software: + PROGMEM now stores the input name table. + I moved the input table to program space. This saves some ram I might need later. + + EEPROM Code Commented Out In Non-Beta + The EEPROM beta code now exists in the non-beta; but it comes commented out. This + is done for the lazy people that don't like/want/know-how to edit code. + + Hardware: + Power-On Reset circuit on 595 removed. + The POR circuit originally held the shift-register reset low long for a brief second + to clear the random start-up state. This was because the old method of controlling the + outputs on the chip resulted in the outputs turning on during the ATMega's initalization. + (They go from high-impedance to low before the code takes over.) But with the new blanking + circuit that's not a problem; it keeps both the 2003 and 595's outputs off untill it goes + logic high in the software. The three components from the POR are now gone, the pull-up on + the 595's enable line changed to a 1k, and the transistor and additional resistor added for + the switch/inverter. It basically reduces overall count by just one component; but it makes + the thing behave better than I expected. + + I'm sure in a lot of situtations this is a bad idea; but since the 595 doesn't seem to care + if it has the reset circuit and the rest of our circuit doesn't care what or if the 595 boots + in a scrambled state...why have it? Since we clock data in to it before pulling blanking high + it won't output incorrect data. + Version 0.1.8: Software: diff --git a/README.md b/README.md index 89cc3bf..1baff16 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Arduino Control for Your Vintage Stereo 05-Jan-2020: Version 0.1.6 - Lots of code clean-up, condensing, rewriting. 06-Jan-2020: Version 0.1.7 - More code clean-up, practical rewrite of main loop. Bitmapped the logo. 09-Jan-2020: Version 0.1.8 - Code consolidation. Additional beta version with EEPROM support. Added utilities. +10-Jan-2020: Version 0.1.9 - Moved input name table to program space. ```` @@ -59,15 +60,15 @@ Click for full resolution. Data is shifted in to a 74HC595 and it's parallel outputs are used to control a ULN2803(or 2003) darlington array to in turn drive a relay. Every effort has been taken to ensure only one relay will be fired at a time to prevent damage -to other audio components. The output of the 74HC595 is controlled by the microcontroller and an RC circuit on the reset -line prevent suprious relays from firing. In version 0.1.5/hardware 1.4 this was slightly modified. A simple transistor -logic inverter now drives both the 74HC595 enable pin as well as the ULN2803/2003's ground line. This was done because -the 2003 I'm using likes to boot up with every output on even when pulling the lines down. Calculating the relays to -draw about 40mA each; trying to sink this through the arduino using the existing logic low for the 595 was probably a -bad idea. So the logic in the software was flipped and the transistor now converts the logic-high to "logic low" and -is capable of sinking something like 800mA if I read the datasheet right. More than enough for the 80mA I predict I'll -need from the thing. While I wanted to keep parts down (and complexity) low; keeping a low number of pins to the micro- -controller is the priority and the transistor and two resistors not only aren't expensive, but meet that goal. +to other audio components. The output of the 74HC595 is controlled by the blanking circuit that also controls the 2003. +In version 0.1.5/hardware 1.4 this was slightly modified. A simple transistor logic inverter now drives both the 74HC595 +enable pin as well as the ULN2803/2003's ground line. This was done because the 2003 I'm using likes to boot up with +every output on even when pulling the lines down. Calculating the relays to draw about 40mA each; trying to sink this +through the arduino using the existing logic low for the 595 was probably a bad idea. So the logic in the software was +flipped and the transistor now converts the logic-high to "logic low" and is capable of sinking something like 800mA if +I read the datasheet right. More than enough for the 80mA I predict I'll need from the thing. While I wanted to keep parts +down (and complexity) low; keeping a low number of pins to the micro-controller is the priority and the transistor and two +resistors not only aren't expensive, but meet that goal. The 2803/2003 arrays include built in snubber diodes for inductive kick-back protection. If you should deviate from this schematic and use discreet diodes, you must add these diodes to your circuit or you will damage the transistors, shift @@ -97,6 +98,10 @@ emulate the original segmented font display of the Denon. # Software +Both the main version and EEPROM beta are essentially the same. The normal version has all the EEPROM code commented out by default +and the beta has the EEPROM code active. This was done for the lazy who don't like/want/know-how to modify code. This won't matter +once I work out the hardware for the interrupt triggering and EEPROM support leaves beta. + This sketch requires the following libaries: - IRRemote (https://github.com/z3t0/Arduino-IRremote) - U8G2 Display Driver (https://github.com/olikraus/u8g2) diff --git a/hifilogix-eeprombeta.ino b/hifilogix-eeprombeta.ino index 021a632..074d5df 100644 --- a/hifilogix-eeprombeta.ino +++ b/hifilogix-eeprombeta.ino @@ -1,9 +1,9 @@ /* - HiFiLOGIX EEPROM BETA (0.1.8 Base) - - dewdude@gmail.com - 08-JAN-2019 + HiFiLOGIX EEROM BETA 0.1.9 - !!! IMPORTANT !!! + dewdude@gmail.com - 09-JAN-2019 + + !!! IMPORTANT !!! IF YOU HAVE DATA AT ADDRESSES 1020 - 1023, THIS SKETCH WILL CHANGE IT. @@ -31,15 +31,25 @@ #include #include #include +#include #include #define di 1022 #define dx 1021 #define db 1020 +#define dt 1023 #include "logo.h" // XBMP data for logo. U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); -const char *inputs[] = {"TAPE-2","TAPE-1","AUX","TUNER","PHONO-2","PHONO-1"}; +const char in0[] PROGMEM = "TAPE-2"; +const char in1[] PROGMEM = "TAPE-1"; +const char in2[] PROGMEM = "AUX"; +const char in3[] PROGMEM = "TUNER"; +const char in4[] PROGMEM = "PHONO-1"; +const char in5[] PROGMEM = "PHONO-2"; + +const char * const inputs[] PROGMEM ={in0,in1,in2,in3,in4,in5}; // Drop the entire array in to program space. + int latchPin = 11; int clockPin = 9; int dataPin = 12; @@ -48,29 +58,33 @@ int blanking = 5; int matrix = A0; IRrecv remote(IRin); decode_results ircode; +char txt[8]; + +void DontCrossTheStreams(byte op, int x, int i) // There's something very important I forgot to tell you. +{ // Don't cross the streams. + strcpy_P(txt, (char*)pgm_read_word(&(inputs[i]))); // Why? + digitalWrite(latchPin, LOW); // It would be bad. + shiftOut(dataPin, clockPin, LSBFIRST, op); // What do you mean, bad? + digitalWrite(latchPin, HIGH); // Imagine all life as you know + u8g2.clearBuffer(); // it stopping instaneously + u8g2.drawStr(x,30,txt); // and every molecule in + u8g2.sendBuffer(); // your body exploding + EEPROM.update(db, op); // at the speed of light. + EEPROM.update(dx, x); // Total protonic reversal. + EEPROM.update(di, i); // That's bad. +} // Important safety tip, thanks Egon. + -void DontCrossTheStreams(byte op, int x, int i) // There's something very important I forgot to tell you. -{// Don't cross the streams. // Why? - digitalWrite(latchPin, LOW); // It would be bad. - shiftOut(dataPin, clockPin, LSBFIRST, op); // What do you mean, bad? - digitalWrite(latchPin, HIGH); // Imagine all life as you know - u8g2.clearBuffer(); // it stopping instaneously - u8g2.drawStr(x,30,inputs[i]); // and every molecule in - u8g2.sendBuffer(); // your body exploding - EEPROM.update(db, op); // at the speed of light. - EEPROM.update(dx, x); // Total protonic reversal. - EEPROM.update(di, i); // That's bad. - // Important safety tip, thanks Egon. -} -void eeprominit() { -if (EEPROM.read(1023) == 'T') { +void eeprominit() { // This checks the EEPROM to see if it's + // been initialized by the code before. +if (EEPROM.read(dt) == 'T') { // Check address 1023 for init flag "T" return; } else { EEPROM.write(db, 16); EEPROM.write(dx, 32); EEPROM.write(di, 2); - EEPROM.write(1023, 'T'); + EEPROM.write(dt, 'T'); } } @@ -88,8 +102,9 @@ void setup() u8g2.drawXBMP(14,4,hifilogix_width,hifilogix_height,hifilogix_bits); } while ( u8g2.nextPage() ); delay(2000); // It takes the Denon about 4.5 seconds to kick speakers on. - u8g2.setFont(u8g2_font_logisoso28_tr); // Moved here since logo is bitmap. - DontCrossTheStreams(EEPROM.read(db),EEPROM.read(dx),EEPROM.read(di)); // THIS IS NO LONGER STATIC IN THE BETA! (yay.) + u8g2.setFont(u8g2_font_logisoso28_tr); + DontCrossTheStreams(EEPROM.read(db),EEPROM.read(dx),EEPROM.read(di)); // THIS IS NO LONGER STATIC IN THE BETA! (yay.) + //DontCrossTheStreams(16,32,2); digitalWrite(blanking,HIGH); // Now drives a logic inverter. } diff --git a/hifilogix.ino b/hifilogix.ino index 56b7bec..6f25c24 100644 --- a/hifilogix.ino +++ b/hifilogix.ino @@ -1,17 +1,31 @@ /* - HiFiLOGIX 0.1.8 - - dewdude@gmail.com - 08-JAN-2019 + HiFiLOGIX 0.1.9 + + dewdude@gmail.com - 09-JAN-2019 */ #include #include #include +#include +/*#include +#define di 1022 +#define dx 1021 +#define db 1020 +#define dt 1023 */ #include "logo.h" // XBMP data for logo. U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); -const char *inputs[] = {"TAPE-2","TAPE-1","AUX","TUNER","PHONO-2","PHONO-1"}; +const char in0[] PROGMEM = "TAPE-2"; +const char in1[] PROGMEM = "TAPE-1"; +const char in2[] PROGMEM = "AUX"; +const char in3[] PROGMEM = "TUNER"; +const char in4[] PROGMEM = "PHONO-1"; +const char in5[] PROGMEM = "PHONO-2"; + +const char * const inputs[] PROGMEM ={in0,in1,in2,in3,in4,in5}; // Drop the entire array in to program space. + int latchPin = 11; int clockPin = 9; int dataPin = 12; @@ -20,17 +34,35 @@ int blanking = 5; int matrix = A0; IRrecv remote(IRin); decode_results ircode; +char txt[8]; -void DontCrossTheStreams(byte op, int x, int i) // There's something I forgot to tell you. -{// Don't cross the streams. // It would be bad. - digitalWrite(latchPin, LOW); // What do you mean, bad? - shiftOut(dataPin, clockPin, LSBFIRST, op); // Imagine all life as you know it - digitalWrite(latchPin, HIGH); // stopping instaneously and every - u8g2.clearBuffer(); // molecule in your body exploding - u8g2.drawStr(x,30,inputs[i]); // At the speed of light. - u8g2.sendBuffer(); // Total protonic reversal. - // That's bad. // Important safety tip, thanks Egon. -} +void DontCrossTheStreams(byte op, int x, int i) // There's something very important I forgot to tell you. +{ // Don't cross the streams. + strcpy_P(txt, (char*)pgm_read_word(&(inputs[i]))); // Why? + digitalWrite(latchPin, LOW); // It would be bad. + shiftOut(dataPin, clockPin, LSBFIRST, op); // What do you mean, bad? + digitalWrite(latchPin, HIGH); // Imagine all life as you know + u8g2.clearBuffer(); // it stopping instaneously + u8g2.drawStr(x,30,txt); // and every molecule in + u8g2.sendBuffer(); // your body exploding + EEPROM.update(db, op); // at the speed of light. + EEPROM.update(dx, x); // Total protonic reversal. + EEPROM.update(di, i); // That's bad. +} // Important safety tip, thanks Egon. + + + +/* void eeprominit() { // This checks the EEPROM to see if it's + // been initialized by the code before. +if (EEPROM.read(dt) == 'T') { // Check address 1023 for init flag "T" + return; + } else { + EEPROM.write(db, 16); + EEPROM.write(dx, 32); + EEPROM.write(di, 2); + EEPROM.write(dt, 'T'); + } +} */ void setup() { @@ -38,6 +70,7 @@ void setup() pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(blanking, OUTPUT); + //eeprominit(); u8g2.begin(); remote.enableIRIn(); u8g2.firstPage(); // Logo is now bitmapped and since I only call it @@ -45,8 +78,9 @@ void setup() u8g2.drawXBMP(14,4,hifilogix_width,hifilogix_height,hifilogix_bits); } while ( u8g2.nextPage() ); delay(2000); // It takes the Denon about 4.5 seconds to kick speakers on. - u8g2.setFont(u8g2_font_logisoso28_tr); // Moved here since logo is bitmap. - DontCrossTheStreams(16,32,2); // THIS IS NO LONGER STATIC IN THE BETA! (yay.) + u8g2.setFont(u8g2_font_logisoso28_tr); + //DontCrossTheStreams(EEPROM.read(db),EEPROM.read(dx),EEPROM.read(di)); // THIS IS NO LONGER STATIC IN THE BETA! (yay.) + DontCrossTheStreams(16,32,2); digitalWrite(blanking,HIGH); // Now drives a logic inverter. } diff --git a/images/schematic.png b/images/schematic.png index d77aae5..b25e324 100644 Binary files a/images/schematic.png and b/images/schematic.png differ diff --git a/images/schematicsmall.png b/images/schematicsmall.png index 60e8aff..09e7d32 100644 Binary files a/images/schematicsmall.png and b/images/schematicsmall.png differ