Version 0.2.0: EEPROM is no longer beta. Beta deleted.

master
Jay 4 years ago
parent 7ff748af1b
commit 264f4198ce

@ -1,5 +1,15 @@
CHANGELOG:
Version 0.2.0:
Software:
EEPROM Support out of beta. Added hardware interrupt routine for it.
Using the EEPROM is now the default action for the software, meaning the beta version
has gone away. This sketch absolutely makes use of the EEPROM as part of it's boot
routine. It will overwrite data on first boot and loads the "default" input every
boot. The update is done via an interrupt. More on that will be explained later as
it will require some power-supply hacking I'll have to design.
Version 0.1.9:
Software:

@ -17,6 +17,7 @@ Arduino Control for Your Vintage Stereo
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.
11-Jan-2020: Version 0.2.0 - EEPROM code now out of beta. Writes with hardware interrupt now.
````
@ -92,15 +93,33 @@ but it's possible I may wind up writing a routine for "self-programming".
As of Version 0.1.4 we now support the SSD1306 based 128x32 OLED Display.
In the future I will be adding some kind of NVRam storage. This will facilitate actually storing configuration options, remote
programming codes, and to store the last-used input. I may also use this to store graphic data for the OLED display to
emulate the original segmented font display of the Denon.
# EEPROM Usage
# Software
Version 0.2.0 brought the EEPROM code out of beta. It is now a default feature of the main version.
THE SKETCH DOESN'T CARE WHAT DATA YOU HAVE AT 1020 - 1023 OR IF YOU HAVE THE CIRCUIT TO PROPERLY USE IT. IT WILL WRITE OVER
IT THE FIRST TIME YOU RUN IT.
YOU MUST CHANGE THE VALUES IF YOUR EEPROM IS SMALLER OR WANT TO USE DIFFERENT ADDRESSES.
The sketch currently uses 4 bytes of EEPROM space to store the input last selected at power off. One byte is used to store the
byte sent to the shift register, one stores the x offset for the display, the other stores the index to the array that contains
the name; the exact same information used for arguments to DontCrossTheStreams(). This information is read during boot.
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.
In order to ensure there's valid data; the fourth byte is used to indicate if the initialization routine has run. If the last
byte contains "T", then we assume the data we want is valid. If T is not found; then the function writes the default data for
the AUX input and writes the initalization flag.
Data is written to the EEPROM by way of a hardware interrupt. The basic idea is to throw a lot of capacitance on to the Arduino
in a way that it's isolated to the Arduino and montior "the other side" of the 5V rail. When the 5V line drops as a result of
turning off the amplifier; the capacitor should power the Arduino long enough to detect the falling state of pin 2 and write the
data to the EEPROM...if necessary.
If you leave pin 2 floating it seems to do nothing. If you connect it to ground it does nothing. If it drops out at the same time
as the Arduino, it does nothing. If you do nothing with this pin the thing behaves just like before; with the exception that the
default never changes.
# Software
This sketch requires the following libaries:
- IRRemote (https://github.com/z3t0/Arduino-IRremote)

@ -1,127 +0,0 @@
/*
HiFiLOGIX EEROM BETA 0.1.9
dewdude@gmail.com - 09-JAN-2019
!!! IMPORTANT !!!
IF YOU HAVE DATA AT ADDRESSES 1020 - 1023, THIS SKETCH WILL CHANGE IT.
IF YOUR EEPROM IS SMALLER, YOU WILL NEED TO CHANGE THE ADDRESSES.
THIS CURRENTLY WRITES TO THE EEPROM EVERY SOURCE CHANGE.
Address 1020 stores the byte to be sent to the shift register.
Address 1021 stores the x offset for the display.
Address 1022 contains the index of the input string array.
Address 1023 contains the letter "T" if defaults exist.
On boot the script looks for the letter "T" at address 1023.
If it exists this is supposed to indicate it's been initialized
and it will continue with the main setup loop. If not, it writes
default values to locations 1020 - 1022 and writes T to 1023.
During the setup loop, the values stored at 1020 - 1022 are
fed as arguments to DontCrossTheStreams. I could probably do
this with a bunch of if loops to read a single byte and translate
that in to the rest...but I don't know how that would affect the
memory.
*/
#include <Wire.h>
#include <U8g2lib.h>
#include <IRremote.h>
#include <avr/pgmspace.h>
#include <EEPROM.h>
#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 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;
int IRin = 7;
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 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()
{
pinMode(latchPin, OUTPUT);
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
do { // once, it doesn't need it's own function.
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);
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.
}
void loop()
{
int mx = analogRead(matrix);
byte icode = 0; // I changed how I handed the inputs.
if (remote.decode(&ircode)) {
icode = ircode.value;
remote.resume();
}
// I don't know if it improves things, but I sure like how much smaller this section is.
if ((mx > 100 && mx < 200) || (icode == 0x97)) DontCrossTheStreams(64,10,0); // The code I originally used to figure out my
if ((mx > 500 && mx < 600) || (icode == 0x67)) DontCrossTheStreams(32,10,1); // remote codes returned 3 bytes in hex. I can't
if ((mx > 900 && mx < 950) || (icode == 0x4F)) DontCrossTheStreams(16,32,2); // remember what that code was, but I only need
if ((mx > 1000) || (icode == 0xCF)) DontCrossTheStreams(8,18,3); // the last bit with the remote I'm using.
if ((mx > 820 && mx < 899) || (icode == 0xE7)) DontCrossTheStreams(6,1,4); // I'm working on making the bare-bones utility I
if ((mx > 700 && mx < 800) || (icode == 0x85)) DontCrossTheStreams(5,1,5); // wrote a bit more user-friendly.
delay(200);
}

@ -1,18 +1,35 @@
/*
HiFiLOGIX 0.1.9
HiFiLOGIX 0.2.0
dewdude@gmail.com - 09-JAN-2019
!!! IMPORTANT NOTICE !!!
As of 0.2.0 EEPROM support is no longer considered to be beta and has been
fully integrated in to the main build. You should be aware of the following:
It uses EEPROM addresses 1020 - 1023
It will erase any data you may have there during the initilization routine.
If your EEPROM is smaller, or you don't want to use 1020 - 1023; then you'll
need to change their #define to match what you want/need.
Pin 2 is used for the hardware interrupt trigger that writes the data. It's
set to run fall. This will be done in hardware by isolating a capacitor for
the Arduino and tying pin 2 to the part of the power supply that will drop
first. The reserve current should last long enough to update the falues before
draining.
*/
#include <Wire.h>
#include <U8g2lib.h>
#include <IRremote.h>
#include <avr/pgmspace.h>
/*#include <EEPROM.h>
#include <EEPROM.h>
#define di 1022
#define dx 1021
#define db 1020
#define dt 1023 */
#define dt 1023
#include "logo.h" // XBMP data for logo.
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
@ -24,7 +41,7 @@ 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.
const char * const inputs[] PROGMEM ={in0,in1,in2,in3,in4,in5};
int latchPin = 11;
int clockPin = 9;
@ -32,11 +49,14 @@ int dataPin = 12;
int IRin = 7;
int blanking = 5;
int matrix = A0;
byte eop = 0;
byte ex = 0;
byte ei = 0;
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.
void DontCrossTheStreams(byte op, byte x, byte 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.
@ -45,14 +65,13 @@ void DontCrossTheStreams(byte op, int x, int i) // There's something
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.
eop = op; ex = x; ei = i; // at the speed of light.
// Total protonic reversal. // That's bad.
}// Important safety tip, thanks Egon.
/* void eeprominit() { // This checks the EEPROM to see if it's
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;
@ -62,7 +81,13 @@ if (EEPROM.read(dt) == 'T') { // Check address 102
EEPROM.write(di, 2);
EEPROM.write(dt, 'T');
}
} */
}
void lastbreath() { // The idea here is to throw a large capacitor on to the voltage rail
EEPROM.write(db, eop); // powering the Arduino; but keep it from powering anything else.
EEPROM.update(dx, ex); // Monitor the "other" 5V rail with pin 2 and trigger an interrupt
EEPROM.update(di, ei); // and rely on the caps charge to keep charge long enough to write.
}
void setup()
{
@ -70,7 +95,7 @@ void setup()
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(blanking, OUTPUT);
//eeprominit();
eeprominit();
u8g2.begin();
remote.enableIRIn();
u8g2.firstPage(); // Logo is now bitmapped and since I only call it
@ -79,9 +104,9 @@ void setup()
} while ( u8g2.nextPage() );
delay(2000); // It takes the Denon about 4.5 seconds to kick speakers on.
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);
DontCrossTheStreams(EEPROM.read(db),EEPROM.read(dx),EEPROM.read(di)); // Read settings stored in EEPROM.
digitalWrite(blanking,HIGH); // Now drives a logic inverter.
attachInterrupt (digitalPinToInterrupt(2), lastbreath, FALLING); // Write the values before your cap discharges!
}
void loop()

Loading…
Cancel
Save