Friday, August 9, 2024

Let microcontrollers talk to eachother

For an index to all my stories click this text

I had an idea for a project that needed a lot of IO pins. That sounds easy as there are several stories on this weblog that demonstrate how to get more output or input pins for your microcontroller.

But this was different. I needed a lot of input pins on a microcontroller and depending on the state of those, certain outputs should be set, and a display should show values. And my microcontroller had not e4nough pins to achieve all this.

So I wondered if it was possible to send the output of the IO pins from one microcontroller to the input IO pins of another microcontroller. And for certain reasons I did not want to use serial communication over UART.

ESP32 to Raspberry Pi Pico

I started with trying to connect an ESP32's IO pin to a Raspberry Pi Pico. As a proof of concept I connected 1 IO pin of the ESP32 as an output to 1 IO pin of the Raspberry Pi Pico that acted as the input. Both operate at 3.3V so this should work.

The programs for both the ESP32 and Raspberry Pi Pico are written in MicroPython.
To get this working you should make sure that your IDE (I am using Thonny) is able to open multiple instances.

This is the breadboardsetup.

The GND of the ESP32 is connected to the GND of the Raspberry Pi Pico. If you do not do this the two will not be able to communicate.
Pin 23 from the ESP32 is connected to Pin 16 of the Raspberry Pi Pico. These are the two pins that are used to make the Microcontrollers communicate with eachother.
The Raspberry Pi pico has a led connected to pin 15. This led is connected with a 200 Ohm current delimiting resistor.

That's all for this first test.


The ESP32 program

Here is the full program.

'''
ESP32
send output to other micro on pin 23)
'''

import time
from machine import Pin

outbut = Pin(23, Pin.OUT)

outbut.value(0)

while True:
      outbut(not outbut())
      print(outbut.value())
      time.sleep(1)


I guess the code speaks for itself. Pin23 is defined as the output pin, and it's value is toggled by outbut(not outbut())

The Raspberry Pi Pico program

'''
Raspberry Pi Pico
get input on pin 16)
'''

import time
from machine import Pin

inpbut = Pin(16, Pin.IN, Pin.PULL_UP )
led = Pin(15, Pin.OUT)

while True:
      print(inpbut.value())
      if (inpbut.value() == 0):
          led.off()
      if (inpbut.value() == 1):
          led.on()
          pass
      time.sleep(1)


As this is just a simple test I did not use an external pullup resistor but defined the input pin (Pin 16) as an input with PULL_UP

The input pin gets its data from the ESP32. If the ESP32 sends a 1 (high) then the Pico's led is set on. If the ESP32 sends a 0 (low) then the Pico's led is set off.

The result

And here is what you will see in Thonny's shell.


On the left is Thonny's instance running the Raspberry Pi Pico. On the right you can see the ESP32 sending out a 1 or 0 every second.

At the breadboard you will see that the led blinks evey second when the Raspberry Pi Pico receives a high (1) signal.

A more advanced experiment.

As a test I attached a pushbutton to the ESP32. The goal was to set the led attached to the Raspberry Pi Pico on when the button attached to the ESP32 is pushed.

The breadboard setup is almost identical to the previous version I only attached a pusbutton with a pull-up resistor to the ESP32.


The only thing different from the previous setup is the attached pusbutton which is connected to pin 34 of the ESP32 with a 10K pull-up resistor.


The new ESP32 micropython program

The programn for the Raspberry Pi Pico remains the same. The only difference is in the program for the ESP32.

'''
ESP32
send output to other micro on pin 23
depending on button state
'''

import time
from machine import Pin

button = Pin(34, Pin.IN)
outbut = Pin(23, Pin.OUT)
led = Pin(2, Pin.OUT)

outbut.value(0)

while True:
      if (button.value() == 0):
          outbut.on()
          print(outbut.value())
      if (button.value() == 1):
          outbut.off()
          print(outbut.value())
      time.sleep(.2)


The program send constantly a 0 (LOW) signal on pin 23 and wait tills the button is pressed. When the button is pressed the signal on pin 23 turns into a 1 and that makes the Pico's led go on.

In real life

This works as I thought it would. In real life you possibly want to send more signals from one microcontroller to another.

Please make sure that both microcontrollers work at the same voltage. An ESP32 and a Raspberry Pi Pico both work at 3.3V.  An Arduino however works at 5V, so connecting that to an ESP32 or Raspberry Pico would fry one of these.

A solution to send more info over few pins would be to use binary coding. I covered that in a previous story :
http://lucstechblog.blogspot.com/2019/07/more-buttons-on-fewer-pins.html

That's all for now.
Have fun


Luc Volders