Read 8 bit parallel data with Arduino Uno

Hello!

I am trying to read the display data of an old drummachine. Data should clock in (with write_enable) twice as 2 * 8 bit and chip_select line low. (see attachments)

Using chip_select_line to interrupt and enable interrupts on write_enable_line. (more chips reads data from the 8-bit parallel bus)

why doesn’t it work :slight_smile:
The CPU in the drummachine runs with a 2 Mhz crystal. Is that too fast for the Arduino??

#include <SoftwareSerial.h>

int buffer[] = {0,0};
boolean j = 0;
boolean cs = 0;

SoftwareSerial mySerial = SoftwareSerial(10, 11); //Rx,  Tx  Using this because 8 bit parallel data enters on pin 0-7

 void setup() {
  
 //Write_enable interrupt setup
  PCICR |= (0<<PCIE0);                 //Disable interrupts on PCIE0
  PCMSK0 |= (1<<PCINT0);               //Set pinmask to register interrupts on pin D8
  MCUCR = (1<<ISC01) | (1<<ISC01);     //trigger at rising edge
  
 //Chip_select interrupt setup
  PCICR |= (1<<PCIE1);                  //Enable interrupts on PCIE1
  PCMSK1 |= (1<<PCINT8);                //Set pinmask to register interrupts on pin A0
  MCUCR = (1<<ISC00) | (1<<ISC01);      //trigger at any change
  
  for (byte i = 0; i <= 10; i++){      //set input pins
  pinMode(i, INPUT);
  }
  pinMode(11, OUTPUT);                //set output pins
  mySerial.begin(9600);              //pin D10 Rx, D11 Tx
 }

void loop() {
 
 mySerial.print(buffer[0], BIN);     //print 8 bit buffer part 1
 mySerial.print(" ");              
 mySerial.println(buffer[1], BIN);   //print 8 bit buffer part 2
}

ISR ( PCINT0_void ) {   // interrupt Write_enable 
  
  buffer[j] = PIND;    //read datalines and place in buffer 
  
  if (j == 0){         //Switch between buffer0 and buffer1
    j = 1;
  }
  else if (j == 1){
   j = 0; 
 }
}


ISR ( PCINT1_void ) {       //interrupt Chip_select

  if (cs == 0){            //Switch between enabling and disabling the write_enable interrupt
    PCICR |= (1<<PCIE0);
    cs = 1;
  }
  else if(cs == 1){
   PCICR |= (0<<PCIE0);
   cs = 0; 
  }
}

data lines.tiff (34.2 KB)

 PCICR |= (0<<PCIE0);

Hint: That doesn’t do what you think it does. In fact it does nothing.

Thanks!

The plan was to disable interrups on D8 (write_enable) whenever A0 (chip_select) is high. chips_select starts high and goes low when write_enable is clocking the two bytes.

PCICR |= (0<<PCIE0); was to ensure that D8 had disabled interrupt at startup.

and A0 interrupt to enable it.

ISR ( PCINT1_void ) {       //interrupt Chip_select

  if (cs == 0){            //Switch between enabling and disabling the write_enable interrupt
    PCICR |= (1<<PCIE0);
    cs = 1;
  }
  else if(cs == 1){
   PCICR |= (0<<PCIE0);
   cs = 0; 
  }
}

Here are some documents i have used. (3 attachments)

http://www.me.ucsb.edu/~me170c/Code/How_to_Enable_Interrupts_on_ANY_pin.pdf

Hitatchi HD61602:HD61603.pdf (1.49 MB)

Kompatibel:
The plan was to disable interrups on D8 (write_enable) whenever A0 (chip_select) is high. chips_select starts high and goes low when write_enable is clocking the two bytes.

To disable the interrupt you want:

PCICR &= ~(1<<PCIE0);

which sets bit PCIE0 to 0.

Thank you!

It is so obvious now why it doesn't work!

The compound bitwise OR operator (|=) is often used with a variable and a constant to "set" (set to 1) particular bits in a variable.
The compound bitwise AND operator (&=) is often used with a variable and a constant to force particular bits in a variable to the LOW state (to 0). This is often referred to in programming guides as "clearing" or "resetting" bits.

There is a conflict between SoftwareSerial and interrupts.

Will try outputting the data over Ethernet.

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 
  0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX };
IPAddress ip(192,168,0,55);

EthernetServer server(80);

volatile int buffer[] = {0,0};
volatile boolean j, cs = 0;
//volatile boolean cs = 0;



 void setup() {
  
 //Write_enable interrupt setup
  PCICR &= ~(1<<PCIE0);                 //Disable interrupts on PCIE0
  PCMSK0 |= (1<<PCINT0);               //Set pinmask to register interrupts on pin D8
  MCUCR = (1<<ISC01) | (1<<ISC00);     //trigger at falling edge
  
 //Chip_select interrupt setup
  PCICR |= (1<<PCIE1);                  //Enable interrupts on PCIE1
  PCMSK1 |= (1<<PCINT8);                //Set pinmask to register interrupts on pin A0

  interrupts();
  
  for (byte i = 0; i <= 7; i++){      //set input pins
  pinMode(i, INPUT);
  }


Ethernet.begin(mac, ip);
server.begin();
  
}


void loop() {
    // listen for incoming clients
    EthernetClient client = server.available();
      if (client) {
 

        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {
              char c = client.read();
              Serial.write(c);

               if (c == '\n' && currentLineIsBlank) {

                  client.println("HTTP/1.1 200 OK");
                  client.println("Content-Type: text/html");
                  client.println("Connection: close");  // the connection will be closed after completion of the response
	          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
                  client.println();
                  client.println("<!DOCTYPE HTML>");
                  client.println("<html>");


                  client.print(buffer[0], BIN);
                  client.print(" ");
                  client.print(buffer[0], BIN);
      
                  client.println("</html>");
                  break;
              }
              if (c == '\n') {
                // you're starting a new line
                currentLineIsBlank = true;
              } 
              else if (c != '\r') {
                // you've gotten a character on the current line
                currentLineIsBlank = false;
              }
        }
      }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
}

ISR ( PCINT0_vect ) {   // interrupt Write_enable 
  
  buffer[j] = PIND;    //read datalines and place in buffer 
  
  if (j == 0){         //Switch between buffer0 and buffer1
    j = 1;
  }
  else if (j == 1){
   j = 0; 
 }
}


ISR ( PCINT1_vect ) {       //interrupt Chip_select

  if (cs == 0){            //Switch between enabling and disabling the write_enable interrupt
    PCICR |= (1<<PCIE0);
    cs = 1;
  }
  else if(cs == 1){
   PCICR |= (0<<PCIE0);
   cs = 0; 
  }
}