Hi, I'm doing a project with the MAX 5487 digital potentiometer and have been trying to implement GUI switches for other functions outside of the DigiPot using GUI switches. I have tried to implement this by using Serial communication to send the data over to the Arduino Mega 2560. While the program works however, it seems to freeze after a certain amount of time without fail for some unexplainable reason. Is there some hidden timeout that I'm not aware of? I am using an 8GB Raspberry Pi 4 for I2C communication and using Python with Thonny.
The code is as follows:
Python:
# Import the required libraries
import tkinter
from tkinter import *
import tkinter.font as tkFont
from PIL import ImageTk, Image
import time
import smbus
import serial
import os
bus = smbus.SMBus(1)
arduinodata = serial.Serial(port='/dev/ttyACM0', baudrate=9600) #initialise serial port to connect to arduino
SLAVE_ADDRESS = 0x08
class App:
def __init__(self, master):
def SendScaleReading(self):
S = scale.get() #retrieve value from slider
print(S)
bus.write_byte(SLAVE_ADDRESS, S) #write data to slave address
frame = Frame(master)
frame.pack()
scale = tkinter.Scale(root,from_=0,to=255,length=700,bg='black',fg='#0000FF', highlightthickness = 0, bd = 0, command=SendScaleReading) #set parameters of slider
scale.place(relx=0.75, rely=0.05)
#scale.place(relx = 0, rely = 0) # set position of slider
fontstyle = tkFont.Font(family='Cambria', size=50) #initialise font
scale['font'] = fontstyle
# cannot use .place()
def ledBoolFn():
global ledBool
# print(ledBool)
if ledBool:
#print('went to on button')
ledBtn.config(image=LedOn_BtnImg)
ledBtn.image = LedOn_BtnImg
#print("on button configured")
ledLabel.config(text="POWER: ON", fg='#00FF00')
# communicating with arduino
arduinodata.write(b'1')
else:
#print('went to off button')
ledBtn.config(image=LedOff_BtnImg)
ledBtn.image = LedOff_BtnImg
#print("off button configured")
ledLabel.config(text="POWER: OFF", fg='#FF0000')
# communicating with arduino
arduinodata.write(b'0')
ledBool = not ledBool
def cbBoolFn():
global cbBool
# print(cbBool)
if cbBool:
#print('went to CbOn button')
circBtn.config(image = CbOn_BtnImg)
circBtn.image = CbOn_BtnImg
#print("CbOn button configured")
cbLabel.config(text="FORWARD", fg='#00FF00')
# communicating with arduino
arduinodata.write(b'3')
else:
#print('went to CbOff button')
circBtn.config(image = CbOff_BtnImg)
circBtn.image = CbOff_BtnImg
# print("CbOff button configured")
cbLabel.config(text="REVERSE", fg='#FF0000')
# communicating with arduino
arduinodata.write(b'2')
cbBool = not cbBool
root = Tk()
app = App(root)
root.config(bg='black')
#root.attributes('-zoomed', True)
#root.state('fullscreen')
rootWidth = root.winfo_screenwidth()
rootHeight = root.winfo_screenheight()
# Create mini window
#canvas = Canvas(root, bg='black', highlightbackground='white')
#canvas.place(relx=0.1, rely=0.03, relheight=0.51, relwidth=0.505)
LedOn_img = Image.open("/home/pi/Downloads/on.png")
LedOff_img = Image.open("/home/pi/Downloads/off.png")
CbOn_img = Image.open("/home/pi/Downloads/on.png")
CbOff_img = Image.open("/home/pi/Downloads/off.png")
# Resize the image using resize() method according to the screen height and width
btnWidth = int(rootWidth / 6.4)
print(btnWidth)
infobtnWidth = int(rootHeight / 10)
print(infobtnWidth)
LedOn_resize_img = LedOn_img.resize((btnWidth, btnWidth))
LedOff_resize_img = LedOff_img.resize((btnWidth, btnWidth))
CbOn_resize_img = CbOn_img.resize((btnWidth, btnWidth))
CbOff_resize_img = CbOff_img.resize((btnWidth, btnWidth))
LedOn_BtnImg = ImageTk.PhotoImage(LedOn_resize_img)
LedOff_BtnImg = ImageTk.PhotoImage(LedOff_resize_img)
CbOn_BtnImg = ImageTk.PhotoImage(CbOn_resize_img)
CbOff_BtnImg = ImageTk.PhotoImage(CbOff_resize_img)
normalWidth = 1920 # Width of monitor screen used to write this code
normalHeight = 1080 # Height of monitor screen used to write this code
percentWidth = rootWidth / (normalWidth / 100)
percentHeight = rootHeight / (normalHeight / 100)
scale = ((percentWidth + percentHeight) / 2) / 100
fontsize = int(14 * scale)
fontsize = 50
fontstyle = tkFont.Font(family='Arial', size=fontsize)
titleFontsize = int(50 * scale)
if titleFontsize < 8:
titleFontsize = 8
TitleFontstyle = tkFont.Font(family="Gothic", size=titleFontsize)
## Labels ##
titleLabel = Label(root, text="MAX5487 DigiPot", font=TitleFontstyle, fg="red", bg="black")
titleLabel.place(relx=0.35, rely=0.05)
ledLabel = Label(root, text="POWER: OFF", font=fontstyle, fg='red', bg='black')
ledLabel.place(relx=0.2, rely=0.65, anchor=N)
cbLabel = Label(root, text="REVERSE", font=fontstyle, fg='red', bg='black')
cbLabel.place(relx=0.5, rely=0.65 , anchor=N)
ledBool = True # boolean for led button
ledBtn = Button(root, image=LedOff_BtnImg, bg='black', bd=0, activebackground='black', highlightthickness = 0, command=ledBoolFn)
ledBtn.place(relx=0.2, rely=0.35, anchor=N)
cbBool = True
circBtn = Button(root, image=LedOff_BtnImg, bg='black', bd=0, activebackground='black', highlightthickness = 0, command=cbBoolFn)
circBtn.place(relx=0.5, rely=0.35, anchor=N)
root.mainloop()
Arduino:
#include <SPI.h>
#include <Wire.h>
#define ADDRESS 0x08
const byte ssPin = 53;
const byte writepotA = B00000001;
const byte writepotB = B00000010;
byte x;
byte y;
void setup() {
Serial.begin(9600);//set baud rate
pinMode(ssPin, OUTPUT);
for (int pinNo = 22; pinNo <= 26; pinNo += 2){
pinMode(pinNo, OUTPUT);
}
digitalWrite(ssPin, LOW);// activate MAX 5487 chip
for (int pinNo = 22; pinNo <= 26; pinNo += 2){
digitalWrite(pinNo, LOW);
}
SPI.begin();// begin Serial Peripheral Interface
SPI.setBitOrder(MSBFIRST);// Most significant bit first
SPI.setDataMode(SPI_MODE3);// set SPI to Mode 3
Wire.begin(ADDRESS);// join i2c bus with address 0x08
Wire.onReceive(receiveEvent); // register event
}
// get called when I2C write occurs
void receiveEvent(int Pos) {
int val = Wire.read();
x = val; // retrieve value from I2C to variable x
// read value sent from python
while (Wire.available() > 0 ) {
Wire.read();
}
}
void loop() {
if (Serial.available()>0)// check is there's a value in the serial port
{
y = Serial.read();// read value from serial port as int
}
switch (y){
case '0':
digitalWrite(22, LOW);
break;
case '1':
digitalWrite(22, HIGH);
break;
case '2':
digitalWrite(24, LOW);
break;
case '3':
digitalWrite(24, HIGH);
break;
default:
for (int pinNo = 22; pinNo <= 26; pinNo += 2){
digitalWrite(pinNo, LOW);
}
}
Serial.print(x);
setPotWiper(writepotA, x);// alter position of wiper A
setPotWiper(writepotB, x);// alter position of wiper B
delay(15);
}
void setPotWiper(int addr, int pos){
pos = constrain(pos, 0, 255);// limit wiper values
digitalWrite(ssPin, LOW);// enable chip
SPI.transfer(addr);// transfer data to address
SPI.transfer(pos);// write wiper position to address
digitalWrite(ssPin, HIGH);// disable chip
}
After troubleshooting for a bit, it appears that the arduinodata.write(b'x') line appears to be causing the problem which made suspect it's got to do with serial communication. Any help is appreciated. Thanks.