Hi. I have an issue when trying to use I2C addresses to interface MAX 5487 digipot and GUI Tkinter switches with an Arduino Mega 2560. I have tried to declare different slave addresses for the switches and slider for the digipot but this would usually lead to at least one of the functions not working. (If I'm not wrong I was getting an error that said return self.func(*args)) The I2C communication is achieved by using the GPIO ports on a Raspberry Pi 4. The only way I managed to fix this was to use the same addresses for both functions. However this would lead to overlapping data. Any help is greatly appreciated.
The python code is as follows:
# 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
SLAVE_ADDRESS1 = 0x10
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='Arial', size=50) #initialise font
scale['font'] = fontstyle
# cannot use .place()
def PowerFn():
global powerBool
# print(ledBool)
if powerBool:
#print('went to on button')
powerBtn.config(image=On_BtnImg)
powerBtn.image = On_BtnImg
#print("on button configured")
powerLabel.config(text="POWER: ON", fg='#00FF00')
# communicating with arduino
# arduinodata.write(string('1', encoding='utf-8'))
bus.write_byte(SLAVE_ADDRESS1, 1) #write data to slave address
else:
#print('went to off button')
powerBtn.config(image=Off_BtnImg)
powerBtn.image = Off_BtnImg
#print("off button configured")
powerLabel.config(text="POWER: OFF", fg='#FF0000')
# communicating with arduino
bus.write_byte(SLAVE_ADDRESS1, 0) #write data to slave address
powerBool = not powerBool
def DirectionFn():
global directionBool
# print(cbBool)
if directionBool:
#print('went to CbOn button')
directionBtn.config(image = On_BtnImg)
directionBtn.image = On_BtnImg
#print("CbOn button configured")
directionLabel.config(text="FORWARD", fg='#00FF00')
# communicating with arduino
bus.write_byte(SLAVE_ADDRESS1, 3) #write data to slave address
else:
#print('went to CbOff button')
directionBtn.config(image = Off_BtnImg)
directionBtn.image = Off_BtnImg
# print("CbOff button configured")
directionLabel.config(text="REVERSE", fg='#FF0000')
# communicating with arduino
bus.write_byte(SLAVE_ADDRESS1, 2) #write data to slave address
directionBool = not directionBool
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)
On_img = Image.open("/home/pi/Downloads/on.png")
Off_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)
On_resize_img = On_img.resize((btnWidth, btnWidth))
Off_resize_img = Off_img.resize((btnWidth, btnWidth))
On_BtnImg = ImageTk.PhotoImage(On_resize_img)
Off_BtnImg = ImageTk.PhotoImage(Off_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)
powerLabel = Label(root, text="POWER: OFF", font=fontstyle, fg='red', bg='black')
powerLabel.place(relx=0.2, rely=0.65, anchor=N)
directionLabel = Label(root, text="REVERSE", font=fontstyle, fg='red', bg='black')
directionLabel.place(relx=0.5, rely=0.65 , anchor=N)
powerBool = True # boolean for led button
powerBtn = Button(root, image=Off_BtnImg, bg='black', bd=0, activebackground='black', highlightthickness = 0, command=PowerFn)
powerBtn.place(relx=0.2, rely=0.35, anchor=N)
directionBool = True
directionBtn = Button(root, image=Off_BtnImg, bg='black', bd=0, activebackground='black', highlightthickness = 0, command=DirectionFn)
directionBtn.place(relx=0.5, rely=0.35, anchor=N)
# Button for closing
exit_button = Button(root, text="Exit", font=fontstyle, fg='white', bg='red', highlightthickness = 0, command=root.destroy)
exit_button.place(relx=0.5, rely=0.9, anchor=N)
root.mainloop()
And here is the code for the Arduino Mega:
#include <SPI.h>
#include <Wire.h>
#define ADDRESS 0x08
#define ADDRESS1 0x10
TwoWire Wire1;
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
Wire1.begin(ADDRESS1);// join i2c bus with address 0x08
Wire.onReceive(receiveEvent); // register event
Wire1.onReceive(receiveEvent1); // register event
}
// get called when I2C write occurs
void receiveEvent(int WiperPos) {
int val = Wire.read();
x = val; // retrieve value from I2C to variable x
// read value sent from python
while (Wire.available() > 0 ) {
Wire.read();
}
}
// get called when I2C write occurs
void receiveEvent1(String Pos) {
byte val1 = Wire1.read();
y = val1; // retrieve value from I2C to variable x
// read value sent from python
while (Wire1.available() > 0 ) {
Wire1.read();
}
}
void loop() {
Serial.print(y);
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
}