Blinking an LED from a Raspberry Pi GPIO signal

First time post, hopefully in the correct board. This seems like this should be a trivial task but the serial output from the Arduino has me confused. I have the components hooked up as shown in the attached file.

My Python code in the Pi

from time import sleep
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

INTERRUPT = 27 # Pin 7 on the header
GPIO.setup(INTERRUPT, GPIO.OUT)

try:
    while True:
        # Set interrupt pin to high
        GPIO.output(INTERRUPT, GPIO.HIGH)
        print("HIGH")
        sleep(5) # 5 second delay
        GPIO.output(INTERRUPT, GPIO.LOW)
        print("Low")
        sleep(5)
finally:
    GPIO.cleanup()

When I run this, it behaves as expected. It outputs "High", waits for 5 seconds and outputs "Low", waits 5 seconds and repeats.

The Arduino code:

#define INTERRUPT 3
#define LED 4
int PREVIOUS_STATE;

void setup() {
  // Start the serial monitor.
  Serial.begin(9600);

  // Initiate digital pins.
  pinMode(INTERRUPT, INPUT);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  PREVIOUS_STATE = LOW;
}

void loop() {
  int state = digitalRead(INTERRUPT);
  // Only set the pin state if the interrupt has been triggered
  if (state == HIGH && PREVIOUS_STATE == LOW){
    digitalWrite(LED, HIGH);
    Serial.println("HIGH");
    PREVIOUS_STATE = HIGH;
  }
  else if (state == LOW && PREVIOUS_STATE == HIGH){
    digitalWrite(LED, LOW);
    PREVIOUS_STATE = LOW;
    Serial.println("LOW");
  }
  else; // No need to handle the other two cases. We only want to change the pin state when the input state changes
}

I'm no stranger to coding, but I'm an electronics novice at best. This arrangement behaves as expected when the signal from the Pi is high, when the signal is low however the serial out rapidly outputs "High" and "Low" alternating. The LED does seem to blink every five seconds though. The confusing parts to me is that the serial monitor implies that there is a changing state, as far as the Arduino is concerned, while the pi output is low causing it to flip-flop between the two states. If I remove the pull-down resistor, I mostly get random blinking and chaos in the serial monitor. If I enable the internal pull-up resistor (after removing the pull-down resistor), I get the opposite problem. The flip-flopping happens when the Pi signal is high.

Any insight would be appreciated.

Can't see the common ground connection to the two devices in your diagram. Where is it?

Paul__B:
Can't see the common ground connection to the two devices in your diagram. Where is it?

Here I reveal how much of a novice I am when it comes to electronics. I'm not sure what you mean by a common ground. I assumed that grounding the led to one of the Pi's ground gpio pins would be sufficient.

You connect the Arduino GND to the Pi GND; either directly or through the breadboard.

sterretje:
You connect the Arduino GND to the Pi GND; either directly or through the breadboard.

I tried with no luck. I get the same behaviour as before. The serial monitor flip-flopping between high and low while the Pi signal is low.

Time to post some clear, bright photos of the circuit, so we can check each of your connections. It still sounds like there is no common ground...

PaulRB:
Time to post some clear, bright photos of the circuit, so we can check each of your connections. It still sounds like there is no common ground...

There is possibly one through USB.

Arduino Uno 5Volts.

Raspberry Pi 3.3V.

Putting 5V onto a Raspberry Pi’s GPIO pin will frack-up the RPi. A single resistor between and going to ground between the RPi and Uno is not a voltage divider. Me, I’d use a logic level shifter.

Idahowalker:
Putting 5V onto a Raspberry Pi's GPIO pin will frack-up the RPi.

The OP is not doing that, rather the other way around, so should be safe. That 10K pull-down resistor the OP is using is only to prevent the arduino input pin from floating until the python code runs (assuming there is a common ground connection, of course).

PaulRB:
The OP is not doing that, rather the other way around, so should be safe. That 10K pull-down resistor the OP is using is only to prevent the arduino input pin from floating until the python code runs (assuming there is a common ground connection, of course).

That was my intention. I've retooled the circuit slightly, using a 4N35 to separate the two circuits (probably should have done this in the first place). Running the same code as the code as before, I get the same behaviour, though now I can see it flickering in the flip-flopping state. Presumably because of the limited response time of the optocoupler.

I used this circuit to do serial between an MCU and a RPi.

Oh, so the RPi has a 'funny' formula for which baud rates are valid, has something to do with a clock rate and dividers. Using the wrong baud rate between a MCU and a RPi can be an issue.

Idahowalker:
I used this circuit to do serial between an MCU and a RPi.

Oh, so the RPi has a 'funny' formula for which baud rates are valid, has something to do with a clock rate and dividers. Using the wrong baud rate between a MCU and a RPi can be an issue.

Good to know, thanks. Serial communication is the end goal of this project but I don't have the logic level converters yet (on their way). I figured I'd take baby steps and if I can't get a LED to blink, then I'd have a hard time getting them to actually talk.
As an aside, I've tried the current circuit since my last post with different Pi's and Arduinos and still get the same behaviour.

You mean this issue:

I'm no stranger to coding, but I'm an electronics novice at best. This arrangement behaves as expected when the signal from the Pi is high, when the signal is low however the serial out rapidly outputs "High" and "Low" alternating.

Not going to figure it out with the information given. A schematic would be great.

What's the size of the resistor on the Pi side of the opto coupler?

In the wide space on the breadboard is a resistor connected to the left side of the wide space. Some breadboards of that size need a jumper wire to bring the applied signal across the wide space. The issue as described reads like a circuit with a floating input.

It has been good practice, for me, to put with a try finally is to use an exception, in the try/finally with in the least a pass.

def fProcess_I():
    while(1):
        evtI.wait()
        try:
            #print( "fProcess_I triggered at %s" %(str(datetime.datetime.now())) )
            with mutexDB:
                oCon_i = mysql.connector.connect( host=certs.sqlHost, user=certs.sqlUser, password=certs.sqlPassword, database=certs.sqlDatabase, autocommit=True)
                oCur_i = oCon_i.cursor()
                #oCur_i.execute( certs.sSQL1, (get_iTemp(), get_iHumidity(), get_iPressure()) )
                oCur_i.execute( certs.sSQL1, (get_iTemp(), get_iPressure(), get_iHumidity()) )
                oCur_i.close()
                oCon_i.close()
        except mysql.connector.Error as err:
            print( "fProcess_I  %d: %s time %s" %(err.args[0], err.args[1], str(datetime.datetime.now())) )
            pass
        finally:
            if( oCon_i.is_connected() ):
                oCon_i.close()
            pass
        evtI.clear()

You can comment out the print and change the except to catch general errors and just have a pass.

You might take a few moments to take a look at attachInterrupt() and pinMode()

Idahowalker:
You mean this issue:
Not going to figure it out with the information given. A schematic would be great.

What's the size of the resistor on the Pi side of the opto coupler?

In the wide space on the breadboard is a resistor connected to the left side of the wide space. Some breadboards of that size need a jumper wire to bring the applied signal across the wide space. The issue as described reads like a circuit with a floating input.

It has been good practice, for me, to put with a try finally is to use an exception, in the try/finally with in the least a pass.

def fProcess_I():

while(1):
       evtI.wait()
       try:
           #print( "fProcess_I triggered at %s" %(str(datetime.datetime.now())) )
           with mutexDB:
               oCon_i = mysql.connector.connect( host=certs.sqlHost, user=certs.sqlUser, password=certs.sqlPassword, database=certs.sqlDatabase, autocommit=True)
               oCur_i = oCon_i.cursor()
               #oCur_i.execute( certs.sSQL1, (get_iTemp(), get_iHumidity(), get_iPressure()) )
               oCur_i.execute( certs.sSQL1, (get_iTemp(), get_iPressure(), get_iHumidity()) )
               oCur_i.close()
               oCon_i.close()
       except mysql.connector.Error as err:
           print( "fProcess_I  %d: %s time %s" %(err.args[0], err.args[1], str(datetime.datetime.now())) )
           pass
       finally:
           if( oCon_i.is_connected() ):
               oCon_i.close()
           pass
       evtI.clear()




You can comment out the print and change the except to catch general errors and just have a pass.

You might take a few moments to take a look at [attachInterrupt()](https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/) and [pinMode()](https://www.arduino.cc/reference/en/language/functions/digital-io/pinmode/)

Thanks, the attachInterrupt() approach worked! I finally have a properly blinking LED. Also thanks for the Python tips, it's a new language for me.
To answer your other question, I use a 1k resistor on the Pi side of the optocoupler (probably overkill, according to the datasheet a 330 would bring it to 10 mA, well under the 50 mA max). A 10k pullup resistor to the collector side of the optocoupler, attached to the 5v line from the Arduino, and a 330 for the LED on the Arduino side.

In my opinion, this topic has taken several bad turns and is now a poor and misleading example to the OP and other beginners who may find it. The original problem remains a mystery. The changes made to arrive at a working solution are over-complex and uneccessary and not the true reason why the circuit is now working, I would say. Although it should work, an opto-isolator is not required in this circuit. Use of attachInterrupt() is also not required. Something else that changed has caused this circuit to start working, but unless the OP reverts to the original circuit and code, and the original problem can be repeated, we will never discover what.

There are many ways to do this, but from what I’ve read and observed, the RPi doesn’t have the current ability to properly power the UNO.

One of my similar projects has the RPi triggering a relay that powers up the UNO. For my purpose, this worked. I also had a project that had both the UNO and RPi running and one of the RPi GPIO going high to trigger action in the UNO.

The KISS says to Keep It Simple.

Just my thoughts.

PaulRB:
In my opinion, this topic has taken several bad turns and is now a poor and misleading example to the OP and other beginners who may find it. The original problem remains a mystery. The changes made to arrive at a working solution are over-complex and uneccessary and not the true reason why the circuit is now working, I would say. Although it should work, an opto-isolator is not required in this circuit. Use of attachInterrupt() is also not required. Something else that changed has caused this circuit to start working, but unless the OP reverts to the original circuit and code, and the original problem can be repeated, we will never discover what.

Thanks for the course correction. I finally figured out what the problem was. It all comes down to my ignorance of how breadboards are laid out. I didn't realize that there was a break in the positive and negative tracks on each side, I had assumed they ran the full length of the breadboard. @Idahowalker mentioned this but I wasn't sure what he was talking about at the time. It took me this long to figure it out. I took the pulldown resistor out and made sure all the grounds were on the same track and it worked perfectly using the original code. So it was a common ground problem the whole time. To verify this, I pulled the ground of the Pi while it was running and I saw the same behaviour as before.
Thanks everyone for the help.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.