Despite the FPGA DueProLogic is officially designed for Arduino, we are going to make the FPGA DueProLogic and Raspberry Pi 4B communicable.
Three tasks are implemented in this tutorial:
(A) Simultaneously press the two push buttons on FPGA to flip the angle of RPi camera.
(B) Raspberry Pi 4B controls the external LED circuit of FPGA.
(C) Live stream the Raspberry Pi Camera on Browser via WIFI
Step 1: Build electronic circuit
After you set up the pin planner, add the yellow lines in the Verilog code as shown in section 2A, 2B, 2C and 2D.
2A: To activate push buttons, you have to use this code
//Push Button Switches
input wire UBA,
input wire UBB
To communicate with Raspberry Pi, you need to add these.
reg sel_send; //activate Raspberry pi
reg rece; //received from raspberry pi
2B: To assigns values to the ports, you should edit the code accordingly
assign XIO_1[3] = start_stop_cntrl;
assign XIO_2[2] = rece; //output HIGH or LOW in LED circuit
assign XIO_2[3] = ~UBA; //push button
assign XIO_2[4] = UBB; //push button
assign XIO_2[5] = sel_send; // FPGA sends signal to raspberry pi
assign sel_read= XIO_5[1]; //FPGA receives signal from raspberry pi
assign c_enable = XIO_5[2]; //XIO_5 -- UB57 -- D17
assign LEDExt = XIO_5[5];
2C: If two push buttons are pressed simultaneously, the FPGA sends HIGH output to Raspberry Pi.
always @(sel_send or UBB or UBA) //send to RPi
begin
if (UBB == 1'b0 && UBA == 1'b0)
sel_send = 1'b1;
else
sel_send = 1'b0;
end
2D: The FPGA reads signal from Raspberry Pi with the clock frequency of 66MHz. The port XIO_2[2] is linked to 'rece'.
always @(sel_read) //read pi
begin
if (sel_read == 1'b1)
rece = 1'b0;
else
rece = 1'b1;
end
Then upload the compiled pof file to the FPGA. If no hardware is detected automatically, click "Hardware Setup" to correct it manually
Open your browser and type your IP address e.g. 192.168.xx.xxx:8000.
After all, the system should work!
Three tasks are implemented in this tutorial:
(A) Simultaneously press the two push buttons on FPGA to flip the angle of RPi camera.
(B) Raspberry Pi 4B controls the external LED circuit of FPGA.
(C) Live stream the Raspberry Pi Camera on Browser via WIFI
Step 1: Build electronic circuit
Step 2: Edit Verilog code
When you buy the FPGA DueProLogic, you should receive a DVD. After you open "Projects_HDL", you should see the original HDL code file
2A: To activate push buttons, you have to use this code
//Push Button Switches
input wire UBA,
input wire UBB
To communicate with Raspberry Pi, you need to add these.
reg sel_send; //activate Raspberry pi
reg rece; //received from raspberry pi
2B: To assigns values to the ports, you should edit the code accordingly
assign XIO_1[3] = start_stop_cntrl;
assign XIO_2[2] = rece; //output HIGH or LOW in LED circuit
assign XIO_2[3] = ~UBA; //push button
assign XIO_2[4] = UBB; //push button
assign XIO_2[5] = sel_send; // FPGA sends signal to raspberry pi
assign sel_read= XIO_5[1]; //FPGA receives signal from raspberry pi
assign c_enable = XIO_5[2]; //XIO_5 -- UB57 -- D17
assign LEDExt = XIO_5[5];
2C: If two push buttons are pressed simultaneously, the FPGA sends HIGH output to Raspberry Pi.
always @(sel_send or UBB or UBA) //send to RPi
begin
if (UBB == 1'b0 && UBA == 1'b0)
sel_send = 1'b1;
else
sel_send = 1'b0;
end
2D: The FPGA reads signal from Raspberry Pi with the clock frequency of 66MHz. The port XIO_2[2] is linked to 'rece'.
always @(sel_read) //read pi
begin
if (sel_read == 1'b1)
rece = 1'b0;
else
rece = 1'b1;
end
Then upload the compiled pof file to the FPGA. If no hardware is detected automatically, click "Hardware Setup" to correct it manually
Step 3: Upload the Raspberry Pi code.
The purple lines allows the FPGA communicating with Raspberry Pi. If you have difficulties to set up live-stream Pi camera, please read chapter 8
Chapter 8: https://roywchpi.blogspot.com/2020/04/8-live-streaming-pi-camera-android.html
import io
import picamera
import logging
import RPi.GPIO as GPIO
import socketserver
import time
from threading import Condition
from http import server
PAGE="""\
<html>
<head>
<title>Raspberry Pi</title>
</head>
<body>
<center><h1>Live Stream from Raspberry Pi Camera</h1></center>
<center><img src="stream.mjpg" width="1024" height="768"></center>
</body>
</html>
"""
A=0;
pin = 6 #GPIO number
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(18,GPIO.OUT)
GPIO.setup(pin,GPIO.IN)
class StreamingOutput(object):
def __init__(self):
self.frame = None
self.buffer = io.BytesIO()
self.condition = Condition()
def write(self, buf):
if buf.startswith(b'\xff\xd8'):
# New frame, copy the existing buffer's content and notify all
# clients it's available
self.buffer.truncate()
with self.condition:
self.frame = self.buffer.getvalue()
self.condition.notify_all()
self.buffer.seek(0)
return self.buffer.write(buf)
class StreamingHandler(server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
self.send_response(301)
self.send_header('Location', '/index.html')
self.end_headers()
elif self.path == '/index.html':
content = PAGE.encode('utf-8')
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.send_header('Content-Length', len(content))
self.end_headers()
self.wfile.write(content)
elif self.path == '/stream.mjpg':
self.send_response(200)
self.send_header('Age', 0)
self.send_header('Cache-Control', 'no-cache, private')
self.send_header('Pragma', 'no-cache')
self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME')
self.end_headers()
try:
while True:
with output.condition:
output.condition.wait()
frame = output.frame
A = GPIO.input(pin) #read FPGA
print(A);
if(A==1):
camera.rotation = 0
GPIO.output(18,GPIO.LOW) #send to FPGA
if(A==0):
camera.rotation = 180
GPIO.output(18,GPIO.HIGH) #send to FPGA
self.wfile.write(b'--FRAME\r\n')
self.send_header('Content-Type', 'image/jpeg')
self.send_header('Content-Length', len(frame))
self.end_headers()
self.wfile.write(frame)
self.wfile.write(b'\r\n')
except Exception as e:
logging.warning(
'Removed streaming client %s: %s',
self.client_address, str(e))
else:
self.send_error(404)
self.end_headers()
class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer):
allow_reuse_address = True
daemon_threads = True
with picamera.PiCamera(resolution='1024x768', framerate=24) as camera:
output = StreamingOutput()
camera.rotation = 180
camera.start_recording(output, format='mjpeg')
try:
address = ('', 8000)
server = StreamingServer(address, StreamingHandler)
server.serve_forever()
finally:
camera.stop_recording()
After all, the system should work!
Video Demo
Comments
Post a Comment