Stap 8: Arduino Sketch bestand
Het volgende bestand van de Arduino schets zorgt ervoor dat de Arduino te wachten op een lijn vanaf de hostcomputer. Als de lijn lezen "Lees alles" is, zal de Arduino het volgende doen:
- Stuur een "START:" lijn naar de hostcomputer.
- Lees alle gegevens van de cartridge en het verzenden van de hostcomputer in HEX, een byte per regel.
- Stuur een ": einde" lijn naar de hostcomputer.
Zodra de gegevens van de cartridge is verstuurd naar de hostcomputer, is de Arduino klaar voor de volgende opdracht vanaf de hostcomputer.
// ColecoVision / ADAM Cartridge Reader // for the Arduino UNO // 2014-11-25 //---------------------------------------------------------------------------------- // Arduino Pins const int gcChipSelectLine[4] = { A0, A1, A2, A3 }; const int gcShiftRegisterClock = 11; const int gcStorageRegisterClock = 12; const int gcSerialAddress = 10; const int gcDataBit[8] = { 2, 3, 4, 5, 6, 7, 8, 9 }; // Shifts a 16-bit value out to a shift register. // Parameters: // dataPin - Arduino Pin connected to the data pin of the shift register. // clockPin - Arduino Pin connected to the data clock pin of the shift register. //---------------------------------------------------------------------------------- void shiftOut16(int dataPin, int clockPin, int bitOrder, int value) { // Shift out highbyte for MSBFIRST shiftOut(dataPin, clockPin, bitOrder, (bitOrder == MSBFIRST ? (value >> 8) : value)); // shift out lowbyte for MSBFIRST shiftOut(dataPin, clockPin, bitOrder, (bitOrder == MSBFIRST ? value : (value >> 8))); } // Select which chip on the cartridge to read (LOW = Active). // Use -1 to set all chip select lines HIGH. //---------------------------------------------------------------------------------- void SelectChip(byte chipToSelect) { for(int currentChipLine = 0; currentChipLine < 4; currentChipLine++) { digitalWrite(gcChipSelectLine[currentChipLine], (chipToSelect != currentChipLine)); } } // Set Address Lines //---------------------------------------------------------------------------------- void SetAddress(unsigned int address) { SelectChip(-1); // Disable shift register output while loading address digitalWrite(gcStorageRegisterClock, LOW); // Write Out Address shiftOut16(gcSerialAddress, gcShiftRegisterClock, MSBFIRST, address); // Enable shift register output digitalWrite(gcStorageRegisterClock, HIGH); int chipToSelect; if (address < 0xA000) { chipToSelect = 0; } else if (address < 0xC000) { chipToSelect = 1; } else if (address < 0xE000) { chipToSelect = 2; } else { chipToSelect = 3; } SelectChip(chipToSelect); } // Read data lines //---------------------------------------------------------------------------------- void ReadDataLines() { const char cHexLookup[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; int highNibble = 0; int lowNibble = 0; boolean dataBits[8]; char byteReadHex[4]; for(int currentBit = 0; currentBit < 8; currentBit++) { dataBits[currentBit] = digitalRead(gcDataBit[currentBit]); } highNibble = (dataBits[7] << 3) + (dataBits[6] << 2) + (dataBits[5] << 1) + dataBits[4]; lowNibble = (dataBits[3] << 3) + (dataBits[2] << 2) + (dataBits[1] << 1) + dataBits[0]; Serial.write(cHexLookup[highNibble]); Serial.write(cHexLookup[lowNibble]); Serial.println(); } // Read all of the data from the cartridge. //---------------------------------------------------------------------------------- void ReadCartridge() { unsigned int baseAddress = 0x8000; Serial.println("START:"); // Read Current Chip (cartridge is 32K, each chip is 8k) for (unsigned int currentAddress = 0; currentAddress < 0x8000; currentAddress++) { SetAddress(baseAddress + currentAddress); ReadDataLines(); } Serial.println(":END"); } // Returns the next line from the serial port as a String. //---------------------------------------------------------------------------------- String SerialReadLine() { const int BUFFER_SIZE = 81; char lineBuffer[BUFFER_SIZE]; int currentPosition = 0; int currentValue; do { // Read until we get the next character do { currentValue = Serial.read(); } while (currentValue == -1); // ignore '\r' characters if (currentValue != '\r') { lineBuffer[currentPosition] = currentValue; currentPosition++; } } while ((currentValue != '\n') && (currentPosition < BUFFER_SIZE)); lineBuffer[currentPosition-1] = 0; return String(lineBuffer); } // Indicate to remote computer Arduino is ready for next command. //---------------------------------------------------------------------------------- void ReadyForCommand() { Serial.println("READY:"); } void setup() { // Setup Serial Monitor Serial.begin(57600); // Setup Chip Select Pins for(int chipLine = 0; chipLine < 4; chipLine++) { pinMode(gcChipSelectLine[chipLine], OUTPUT); } // Setup Serial Address Pins pinMode(gcShiftRegisterClock, OUTPUT); pinMode(gcStorageRegisterClock, OUTPUT); pinMode(gcSerialAddress, OUTPUT); // Setup Data Pins for(int currentBit = 0; currentBit < 8; currentBit++) { pinMode(gcDataBit[currentBit], INPUT_PULLUP); } while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only. } // Reset Output Lines SetAddress(0); ReadyForCommand(); } void loop() { if (Serial.available() > 0) { String lineRead = SerialReadLine(); lineRead.toUpperCase(); if (lineRead == "READ ALL") { ReadCartridge(); } // lineRead = "Read All" ReadyForCommand(); } // Serial.available }
Als je gelukkig dat genoeg om te worden met behulp van een Arduino board met 29 of meer digitale I/O pinnen (b.v. de inachtneming van de Arduino Arduino MEGA ADK, Arduino Mega 2560, enz) en u geen gebruik maakt van de verschuiving registreren circuit, de SetAddress functie in de schets bestand hierboven moet worden herschreven.