That I hadn't thought of. I guess my thinking is that current_character is reset when I call for the next byte from the serial buffer. Is that not how this works?
current_character = Serial.read();
current_character = current_character + (digitalRead(Data_BUS[Data_Pin]) << Data_Pin);
Need a function
Void Address_to_595(int Memory_Address)
This function should do everything needed by the 595's to get "Memory_Address" on outputs of 595's
void writebyte(byte byteValue)
Byte readbyte()
The address is at the memory chip's address pins.
Do every thing else needed by memory chip.
Should take care of Arduino data buss direction and change it if needed.
Test and actual program will use these three functions.
/* This is the source file for the EPROM Programmer! The pin declarations in this file are specifically setup
* for the Arduino Micro, however you can modify the pins to fit your own Arduino Board. This code is paired with a python
* script that sends the hex file byte by byte to the Arduino, which will then put it into the correct address of the memory
*
* The hardware for this programmer is two 74HC595 Shift Registers driving the address BUS, with the data BUS and control
* pins directly connected to the Arduino Digital IO
*
* For more information please visit my website at: [url=http://www.RCtalesofarookie.weebly.com]www.RCtalesofarookie.weebly.com[/url]
*
* Created by Sam Maxwell
* FEB 2016
*/
// Constant Variables that hold pin assignments, please change these for your specific Ardunio Board
// Variables for the 74HC595 Shift Registers, used to drive the address BUS
const int Serial_Clock = 12;
const int Register_Clock = 10;
const int register_output_enable = 11;
const int Serial_Output = 9;
// Variables for the Memory Control Pins
const int memory_write_enable = 0;
const int memory_chip_enable = 1;
const int memory_output_enable = 14;
// Variables for the Data BUS
int Data_BUS[] = {2, 3, 4, 5, 6, 7, 8, 13};
// Variables for storing the current character and the current address
int current_address = 0;
// Main Code
// Setup
void setup(){
// Beginning Serial Communication with PC, used for communication with Python Script, as well as for debugging
Serial.begin(9600); // Serial at 9600 Baud
// Assigning Pin Modes that remain constant regardless of the function
// Shift Register Pin Modes
pinMode(Serial_Clock, OUTPUT);
pinMode(Register_Clock, OUTPUT);
pinMode(register_output_enable, OUTPUT);
pinMode(Serial_Output, OUTPUT);
// Memory Control Pin Modes
pinMode(memory_write_enable, OUTPUT);
pinMode(memory_chip_enable, OUTPUT);
pinMode(memory_output_enable, OUTPUT);
// IMPORTANT!!! Pin Mode assignments for the data BUS occur during the Read and Write functions as pin modes change depending on the function being used
// Making sure pins are at correct levels before cycles begin
// Shift Registers
digitalWrite(register_output_enable, HIGH);
// Memory Control Pin Levels
digitalWrite(memory_write_enable, HIGH);
digitalWrite(memory_chip_enable, HIGH);
digitalWrite(memory_output_enable, HIGH);
}
void loop(){
// Setting Local Variables
byte current_character = Serial.read();
String current_mode = "Write";
// Executing the corresponding function
if(current_mode == "Write"){
current_address = 0;
while(current_address < 35000){ // Python Script Prints } if the end of the file has been reached
if(Serial.available() > 0){
Increment_Address();
Serial.print("");
Read();
Serial.print("");
Write();
Serial.print("");
Read();
Serial.println("");
}
}
}
if(current_mode == "Read"){
current_address = 0;
while(current_address < 35000){
Increment_Address();
Read(); // Executing the Read Function if current_mode == Read
}
}
}
void Write(){
// Write Cycle
// Declaring Local Variables
byte current_character = 01000111;
// Setting Data BUS Pin Modes to OUTPUT for Writing
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
pinMode(Data_BUS[Data_Pin], OUTPUT);
}
// Setting Data Bus Values
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
digitalWrite(Data_BUS[Data_Pin], bitRead(current_character, Data_Pin));
}
// Setting Memory Control Pins
digitalWrite(memory_output_enable, HIGH);
digitalWrite(memory_chip_enable, LOW);
digitalWrite(memory_write_enable, LOW);
// Sending character that is going to be written over serial port for python script
Serial.print("Current Character: ");
Serial.print(current_character);
// Delay to allow Data to become valid
delay(2);
// Setting Memory Control Pins
digitalWrite(memory_write_enable, HIGH);
digitalWrite(memory_chip_enable, HIGH);
}
void Read(){
// Read Cycle
// Declaring Local Variables
byte current_character;
byte current_string;
// Setting Data BUS Pin Modes to INPUT for Reading
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
pinMode(Data_BUS[Data_Pin], INPUT);
}
// Setting Memory Control Pins
digitalWrite(memory_write_enable, HIGH);
digitalWrite(memory_chip_enable, LOW);
digitalWrite(memory_output_enable, LOW);
// Delay to allow Data to become valid
delay(2);
// Reading Data
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
current_character = (digitalRead(Data_BUS[Data_Pin]) << Data_Pin);
current_string += current_character;
}
// Setting Memory Control Pins
digitalWrite(memory_output_enable, HIGH);
digitalWrite(memory_chip_enable, HIGH);
// Printing current character over the serial port for the python script
Serial.print("Current String");
Serial.print(current_string);
}
void Increment_Address(){
// Setting Shift Register Control Pins
digitalWrite(register_output_enable, HIGH);
digitalWrite(Register_Clock, LOW);
// Shifting Out Current Address Value
// Shifting Out High Byte
shiftOut(Serial_Output, Serial_Clock, MSBFIRST, highByte(current_address));
// Shifting Out Low Byte
shiftOut(Serial_Output, Serial_Clock, MSBFIRST, lowByte(current_address));
// Setting Shift Register Control Pins
digitalWrite(Register_Clock, HIGH);
digitalWrite(register_output_enable, LOW);
// Incrementing the value of current_address by one
current_address = current_address + 1;
Serial.print("Current Address");
Serial.print(current_address);
}
void Write(){
// Write Cycle
// Declaring Local Variables
byte current_character = 01000111;
// Variables for the Data BUS
int Data_BUS[] = {2, 3, 4, 5, 6, 7, 8, 13};
With functions a bidirectional data buss. More Arduino pins could be like this. /* This is the source file for the EPROM Programmer! The pin declarations in this file are specifically setup
* for the Arduino Micro, however you can modify the pins to fit your own Arduino Board. This code is paired with a python
* script that sends the hex file byte by byte to the Arduino, which will then put it into the correct address of the memory
*
* The hardware for this programmer is two 74HC595 Shift Registers driving the address BUS, with the data BUS and control
* pins directly connected to the Arduino Digital IO
*
* For more information please visit my website at: [url=http://www.RCtalesofarookie.weebly.com]www.RCtalesofarookie.weebly.com[/url]
*
* Created by Sam Maxwell
* FEB 2016
*/
// Constant Variables that hold pin assignments, please change these for your specific Ardunio Board
// Variables for the 74HC595 Shift Registers, used to drive the address BUS
const int Serial_Clock = 12;
const int Register_Clock = 10;
const int register_output_enable = 11;
const int Serial_Output = 9;
// Variables for the Memory Control Pins
const int memory_write_enable = 0;
const int memory_chip_enable = 1;
const int memory_output_enable = 14;
// Variables for the Data BUS
int Data_BUS[] = {2, 3, 4, 5, 6, 7, 8, 13};
// Variables for storing the current character and the current address
int current_address = 0;
// Main Code
// Setup
void setup(){
// Beginning Serial Communication with PC, used for outputting what the system is doing.
Serial.begin(9600);
// Assigning Pin Modes that remain constant regardless of the function
// Shift Register Pin Modes
pinMode(Serial_Clock, OUTPUT);
pinMode(Register_Clock, OUTPUT);
pinMode(register_output_enable, OUTPUT);
pinMode(Serial_Output, OUTPUT);
// Memory Control Pin Modes
pinMode(memory_write_enable, OUTPUT);
pinMode(memory_chip_enable, OUTPUT);
pinMode(memory_output_enable, OUTPUT);
// Making sure pins are at correct levels before cycles begin
// Shift Registers
digitalWrite(register_output_enable, HIGH);
// Memory Control Pin Levels
digitalWrite(memory_write_enable, HIGH);
digitalWrite(memory_chip_enable, HIGH);
digitalWrite(memory_output_enable, HIGH);
}
void loop(){
// Setting Shift Register Control Pins
digitalWrite(register_output_enable, HIGH);
digitalWrite(Register_Clock, LOW);
// Shifting Out Current Address Value
// Shifting Out High Byte
shiftOut(Serial_Output, Serial_Clock, MSBFIRST, highByte(current_address));
// Shifting Out Low Byte
shiftOut(Serial_Output, Serial_Clock, MSBFIRST, lowByte(current_address));
// Setting Shift Register Control Pins
digitalWrite(Register_Clock, HIGH);
digitalWrite(register_output_enable, LOW);
// Incrementing the value of current_address by one
Serial.print("Current Address: ");
Serial.println(current_address);
current_address = current_address + 1;
// Delay
delay(100);
}
/* This is the source file for the EPROM Programmer! The pin declarations in this file are specifically setup
* for the Arduino Micro, however you can modify the pins to fit your own Arduino Board. This code is paired with a python
* script that sends the hex file byte by byte to the Arduino, which will then put it into the correct address of the memory
*
* The hardware for this programmer is two 74HC595 Shift Registers driving the address BUS, with the data BUS and control
* pins directly connected to the Arduino Digital IO
*
* For more information please visit my website at: [url=http://www.RCtalesofarookie.weebly.com]www.RCtalesofarookie.weebly.com[/url]
*
* Created by Sam Maxwell
* FEB 2016
*/
// Constant Variables that hold pin assignments, please change these for your specific Ardunio Board
// Variables for the 74HC595 Shift Registers, used to drive the address BUS
const int Serial_Clock = 12;
const int Register_Clock = 10;
const int register_output_enable = 11;
const int Serial_Output = 9;
// Variables for the Memory Control Pins
const int memory_write_enable = 0;
const int memory_chip_enable = 1;
const int memory_output_enable = 14;
// Variables for the Data BUS
int Data_BUS[] = {2, 3, 4, 5, 6, 7, 8, 13};
// Variables for storing the current character and the current address
int current_address = 0;
char current_character = '0';
// Main Code
// Setup
void setup(){
// Beginning Serial Communication with PC, used for outputting what the system is doing.
Serial.begin(9600);
// Assigning Pin Modes that remain constant regardless of the function
// Shift Register Pin Modes
pinMode(Serial_Clock, OUTPUT);
pinMode(Register_Clock, OUTPUT);
pinMode(register_output_enable, OUTPUT);
pinMode(Serial_Output, OUTPUT);
// Memory Control Pin Modes
pinMode(memory_write_enable, OUTPUT);
pinMode(memory_chip_enable, OUTPUT);
pinMode(memory_output_enable, OUTPUT);
// Making sure pins are at correct levels before cycles begin
// Shift Registers
digitalWrite(register_output_enable, HIGH);
// Memory Control Pin Levels
digitalWrite(memory_write_enable, HIGH);
digitalWrite(memory_chip_enable, HIGH);
digitalWrite(memory_output_enable, HIGH);
// Setting Data BUS Pin Modes to OUTPUT for Writing
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
pinMode(Data_BUS[Data_Pin], OUTPUT);
}
}
void loop(){
}
void Increment_Address(){
// Setting Shift Register Control Pins
digitalWrite(register_output_enable, HIGH);
digitalWrite(Register_Clock, LOW);
// Shifting Out Current Address Value
// Shifting Out High Byte
shiftOut(Serial_Output, Serial_Clock, MSBFIRST, highByte(current_address));
// Shifting Out Low Byte
shiftOut(Serial_Output, Serial_Clock, MSBFIRST, lowByte(current_address));
// Setting Shift Register Control Pins
digitalWrite(Register_Clock, HIGH);
digitalWrite(register_output_enable, LOW);
// Incrementing the value of current_address by one
Serial.print("Current Address: ");
Serial.println(current_address);
current_address = current_address + 1;
// Delay
delay(100);
}
void Write(){
// Writing the Current Character onto the Data Bus
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
digitalWrite(Data_BUS[Data_Pin], bitRead(current_character, Data_Pin));
}
}
doing the following
Address_to_595(1000)
byte_before = readbyte()
writebyte(B01000111)
byte_after = readbyte()
Address_to_595(1050)
writebyte(B01010111)
Address_to_595(1000)
byte_check = readbyte()
Address_to_595(1050)
byte_check1 = readbyte()
after that
byte_after == byte_check == B01000111
byte_check1 == B01010111
With the functions being passed the data or returning the data, arrays are easy to use.
Time to see if I can actually write something into memory and then read it out again.
boolean Simple_Test(){
Address_to_595(1000)
byte_before = readbyte()
writebyte(B01000111)
byte_after = readbyte()
Address_to_595(1050)
writebyte(B01010111)
Address_to_595(1000)
byte_check = readbyte()
Address_to_595(1050)
byte_check1 = readbyte()
}
/* This is the source file for the EPROM Programmer! The pin declarations in this file are specifically setup
* for the Arduino Micro, however you can modify the pins to fit your own Arduino Board. This code is paired with a python
* script that sends the hex file byte by byte to the Arduino, which will then put it into the correct address of the memory
*
* The hardware for this programmer is two 74HC595 Shift Registers driving the address BUS, with the data BUS and control
* pins directly connected to the Arduino Digital IO
*
* For more information please visit my website at: [url=http://www.RCtalesofarookie.weebly.com]www.RCtalesofarookie.weebly.com[/url]
*
* Created by Sam Maxwell
* FEB 2016
*/
// Constant Variables that hold pin assignments, please change these for your specific Ardunio Board
// Variables for the 74HC595 Shift Registers, used to drive the address BUS
const int Serial_Clock = 12;
const int Register_Clock = 10;
const int register_output_enable = 11;
const int Serial_Output = 9;
// Variables for the Memory Control Pins
const int memory_write_enable = A0;
const int memory_chip_enable = A1;
const int memory_output_enable = A2;
int Read_Write; // Read Cycle = 0, Write Cycle = 1
// Variables for the Data BUS
int Data_BUS[] = {2, 3, 4, 5, 6, 7, 8, 13};
// Variables for storing the ROM File and the current address
int current_address = 0;
int ROM_Array[] = {0x3B, 0x3C, 0x3A, 0x3B, 0x3D};
// Main Code
// Setup
void setup(){
// Beginning Serial Communication with PC, used for outputting what the system is doing.
Serial.begin(9600);
// Assigning Pin Modes that remain constant regardless of the function
// Shift Register Pin Modes
pinMode(Serial_Clock, OUTPUT);
pinMode(Register_Clock, OUTPUT);
pinMode(register_output_enable, OUTPUT);
pinMode(Serial_Output, OUTPUT);
// Memory Control Pin Modes
pinMode(memory_write_enable, OUTPUT);
pinMode(memory_chip_enable, OUTPUT);
pinMode(memory_output_enable, OUTPUT);
// Making sure pins are at correct levels before cycles begin
// Shift Registers
digitalWrite(register_output_enable, HIGH);
// Memory Control Pin Levels
digitalWrite(memory_write_enable, HIGH);
digitalWrite(memory_chip_enable, HIGH);
digitalWrite(memory_output_enable, HIGH);
}
void loop(){
Read();
delay(2000);
Serial.print(" ");
Write();
delay(2000);
Serial.print(" ");
Read();
delay(2000);
Serial.print(" ");
Increment_Address();
if(current_address > 33000){
Serial.println("Memory Programmed!");
Serial.println("Please Verify that the program is correct!");
while(1){
}
}
}
void Increment_Address(){
// Setting Memory Controls
digitalWrite(memory_chip_enable, HIGH);
// Setting Shift Register Control Pins
digitalWrite(register_output_enable, HIGH);
digitalWrite(Register_Clock, LOW);
// Shifting Out Current Address Value
// Shifting Out High Byte
shiftOut(Serial_Output, Serial_Clock, MSBFIRST, highByte(current_address));
// Shifting Out Low Byte
shiftOut(Serial_Output, Serial_Clock, MSBFIRST, lowByte(current_address));
// Setting Shift Register Control Pins
digitalWrite(Register_Clock, HIGH);
digitalWrite(register_output_enable, LOW);
// Incrementing the value of current_address by one
Serial.print("A: ");
Serial.println(current_address);
current_address = current_address + 1;
// Delay
delay(2);
}
void Write(){
// Setting Data BUS Pin Modes to OUTPUT for Writing
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
pinMode(Data_BUS[Data_Pin], OUTPUT);
}
// Setting Current Character
int current_byte = ROM_Array[current_address];
// Sending Data to Serial Terminal
Serial.print("W: ");
Serial.print(current_byte);
// Writing the Current Character onto the Data Bus
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
digitalWrite(Data_BUS[Data_Pin], bitRead(current_byte, Data_Pin));
}
// Setting Memory Control Pins
Read_Write = 1;
Memory_Control();
// Delay
delay(2);
// Setting Memory Control Pins
digitalWrite(memory_chip_enable, HIGH);
digitalWrite(memory_write_enable, HIGH);
digitalWrite(memory_output_enable, HIGH);
}
void Read(){
// Setting Data BUS Pin Modes to INPUT for Reading
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
pinMode(Data_BUS[Data_Pin], INPUT);
}
// Resetting Current String
int current_byte = 0;
// Setting Memory Control Pins
Read_Write = 0;
Memory_Control();
// Delay
delay(2);
// Reading Data
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
int current_bit = (digitalRead(Data_BUS[Data_Pin]) << Data_Pin);
current_byte += current_bit;
}
// Setting Memory Control Pins
digitalWrite(memory_chip_enable, HIGH);
digitalWrite(memory_output_enable, HIGH);
// Sending Data to Serial Terminal
Serial.print("R: ");
Serial.print(current_byte);
}
void Memory_Control(){
// If we are in a Read Cycle
if(Read_Write == 0){
digitalWrite(memory_write_enable, HIGH);
digitalWrite(memory_chip_enable, LOW);
digitalWrite(memory_output_enable, LOW);
}
// If we are in a Write Cycle
if(Read_Write == 1){
digitalWrite(memory_output_enable, HIGH);
digitalWrite(memory_chip_enable, LOW);
digitalWrite(memory_write_enable, LOW);
}
}
That awesome feeling of success! Can't thank you enough for your help guys! I just need to modify the control pins for the EPROM's, and then I'm good too go I think. After I have typed the whole of the ROM file into the ROM_Array[] that is.
I'm full of mistakes! The system is still working as far as I can tell, but I forgot that I had moved some of the jumper leads from the data BUS to the data pins on the memory. When I was looking at the data that was coming back from the system before I remedied my mistake, I was seeing rare occurrences where the data would be wrong, but it would be write for the same value one cycle later. Having moved the jumper leads back to the correct place the system is working very reliably.
My question is, how was the data coming through when I had the jumper leads one row off on every data line. What I've learnt in physics tells me it's either something to do with the magnetic fields induced in around the tracks, although they would be very small. Or some kind of capacitance?
/* This is the source file for the EPROM Programmer! The pin declarations in this file are specifically setup
* for the Arduino Micro, however you can modify the pins to fit your own Arduino Board. This code is paired with a python
* script that sends the hex file byte by byte to the Arduino, which will then put it into the correct address of the memory
*
* The hardware for this programmer is two 74HC595 Shift Registers driving the address BUS, with the data BUS and control
* pins directly connected to the Arduino Digital IO
*
* For more information please visit my website at: [url=http://www.RCtalesofarookie.weebly.com]www.RCtalesofarookie.weebly.com[/url]
*
* Created by Sam Maxwell
* FEB 2016
*/
// Constant Variables that hold pin assignments, please change these for your specific Ardunio Board
// Variables for the 74HC595 Shift Registers, used to drive the address BUS
const int Serial_Clock = 12;
const int Register_Clock = 10;
const int register_output_enable = 11;
const int Serial_Output = 9;
// Variables for the Memory Control Pins
const int memory_chip_enable = A1;
const int memory_output_enable = A2;
int Read_Write; // Read Cycle = 0, Write Cycle = 1
// Variables for the Data BUS
int Data_BUS[] = {2, 3, 4, 5, 6, 7, 8, 13};
// Variables for storing the ROM File and the current address
int current_address = 0;
// Main Code
// Setup
void setup(){
// Beginning Serial Communication with PC, used for outputting what the system is doing.
Serial.begin(9600);
// Assigning Pin Modes that remain constant regardless of the function
// Shift Register Pin Modes
pinMode(Serial_Clock, OUTPUT);
pinMode(Register_Clock, OUTPUT);
pinMode(register_output_enable, OUTPUT);
pinMode(Serial_Output, OUTPUT);
// Memory Control Pin Modes
pinMode(memory_chip_enable, OUTPUT);
pinMode(memory_output_enable, OUTPUT);
// Making sure pins are at correct levels before cycles begin
// Shift Registers
digitalWrite(register_output_enable, HIGH);
// Memory Control Pin Levels
digitalWrite(memory_chip_enable, HIGH);
digitalWrite(memory_output_enable, HIGH);
}
void loop(){
Read();
delay(10);
Serial.print(" ");
delay(100);
Increment_Address();
if(current_address > 33000){
Serial.println("Memory Programmed!");
Serial.println("Please Verify that the program is correct!");
while(1){
}
}
}
void Increment_Address(){
// Setting Memory Controls
digitalWrite(memory_chip_enable, HIGH);
// Setting Shift Register Control Pins
digitalWrite(register_output_enable, HIGH);
digitalWrite(Register_Clock, LOW);
// Shifting Out Current Address Value
// Shifting Out High Byte
shiftOut(Serial_Output, Serial_Clock, MSBFIRST, highByte(current_address));
// Shifting Out Low Byte
shiftOut(Serial_Output, Serial_Clock, MSBFIRST, lowByte(current_address));
// Setting Shift Register Control Pins
digitalWrite(Register_Clock, HIGH);
digitalWrite(register_output_enable, LOW);
// Incrementing the value of current_address by one
Serial.print("A: ");
Serial.println(current_address);
current_address = current_address + 1;
// Delay
delay(2);
}
void Write(){
// Setting Data BUS Pin Modes to OUTPUT for Writing
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
pinMode(Data_BUS[Data_Pin], OUTPUT);
}
// Setting Current Character
char current_byte = Serial.read();
// Sending Data to Serial Terminal
Serial.print("W: ");
Serial.print(current_byte);
// Writing the Current Character onto the Data Bus
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
digitalWrite(Data_BUS[Data_Pin], bitRead(current_byte, Data_Pin));
}
// Setting Memory Control Pins
Read_Write = 1;
Memory_Control();
// Delay
delay(2);
// Setting Memory Control Pins
digitalWrite(memory_chip_enable, HIGH);
digitalWrite(memory_output_enable, HIGH);
}
void Read(){
// Setting Data BUS Pin Modes to INPUT for Reading
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
pinMode(Data_BUS[Data_Pin], INPUT);
}
// Resetting Current String
int current_byte = 0;
// Setting Memory Control Pins
Read_Write = 0;
Memory_Control();
// Delay
delay(2);
// Reading Data
for(int Data_Pin = 0; Data_Pin < 8; Data_Pin++){
int current_bit = (digitalRead(Data_BUS[Data_Pin]) << Data_Pin);
current_byte += current_bit;
}
// Setting Memory Control Pins
digitalWrite(memory_chip_enable, HIGH);
digitalWrite(memory_output_enable, HIGH);
// Sending Data to Serial Terminal
Serial.print("R: ");
Serial.print(current_byte);
}
void Memory_Control(){
// If we are in a Read Cycle
if(Read_Write == 0){
digitalWrite(memory_chip_enable, HIGH);
digitalWrite(memory_output_enable, LOW);
}
// If we are in a Write Cycle
if(Read_Write == 1){
digitalWrite(memory_output_enable, HIGH);
digitalWrite(memory_chip_enable, LOW);
}
}