Hello,
I am trying to use Arduino to generate PWM signals and modify the frequency of PWM signals wile they are running using a user interface created with Python. I tried doing so with Pyserial.
When modifying frequency through Arduino's serial monitor it works properly. However, when I try to change the frequency with through Python there is no change. What could be the problem?
In Python the frequency change should happen at def start after presing the button
Arduino code:
float freq = 109000;
float duty_cycle = 0.3;
int set;
void setup() {
pinMode(9, OUTPUT); //output A
pinMode(10, OUTPUT); //output B
TCCR1A = 0; //clear timer registers
TCCR1B = 0;
TCNT1 = 0;
TCCR1B |= _BV(CS10); //no prescaler
//ICR1 = 73;//freq = 7987412/ICR1;
//OCR1A = 52;
//OCR1A = 0.7297*ICR1;
//OCR1B = ICR1 - OCR1A;
//OCR1A = 20; //Pin 9 match
//output A set rising/clear falling
TCCR1A |= _BV(COM1A1) | _BV(COM1A0); //output A set rising/clear falling
//OCR1B = 54; //Pin 10 match
//output B clear rising/set falling
TCCR1A |= _BV(COM1B1); //output B clear rising/set falling
TCCR1B |= _BV(WGM13); //PWM mode with ICR1 Mode 10
TCCR1A |= _BV(WGM11); //WGM13:WGM10 set 1010
Serial.begin(9600);
//ICR1 = 73;//freq = 7987412/ICR1;
//OCR1A = 50;
//OCR1B = ICR1 - OCR1A;
}
void loop() {
if(duty_cycle>0.4){
duty_cycle = 0.4;
}
set = 7987412/freq;
ICR1 = set;//freq = 7987412/ICR1;
OCR1B = duty_cycle*ICR1;
OCR1A = ICR1 - OCR1B;
if(ICR1>0){
Serial.println(ICR1);
delay(500);
}
if(Serial.available()>0){
freq = Serial.parseFloat();
}
}
Python code:
import sys
import PyQt5
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
import serial
import time
import serial.tools.list_ports
import struct
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("Arduino GUI")
self.setFixedSize(QSize(800,640))
global pagelayout
pagelayout = QVBoxLayout()
button_layout = QHBoxLayout()
label_layout = QHBoxLayout()
spinbox_layout = QHBoxLayout()
port_layout = QHBoxLayout()
freq_layout = QHBoxLayout()
self.stacklayout = QStackedLayout()
pagelayout.addLayout(button_layout)
pagelayout.addLayout(label_layout)
pagelayout.addLayout(spinbox_layout)
pagelayout.addLayout(port_layout)
pagelayout.addLayout(freq_layout)
pagelayout.addLayout(self.stacklayout)
#Port button
btn = QPushButton("Port")
btn.pressed.connect(self.find_port)
button_layout.addWidget(btn)
#Start button
btn = QPushButton("Start")
btn.pressed.connect(self.start)
button_layout.addWidget(btn)
#Stop button
btn = QPushButton("Stop")
btn.pressed.connect(self.stop)
button_layout.addWidget(btn)
#Freq label
label = QLabel("Frequency")
label_layout.addWidget((label))
#DC label
label = QLabel("Duty cycle")
label_layout.addWidget((label))
#Freq spinbox
global spnb_f
spnb_f = QDoubleSpinBox()
spinbox_layout.addWidget(spnb_f)
spnb_f.setDecimals(0)
spnb_f.setMinimum(10000)
spnb_f.setMaximum(500000)
spnb_f.setSingleStep(1)
#DC spinbox
spnb_dc = QDoubleSpinBox()
spinbox_layout.addWidget(spnb_dc)
spnb_dc.setMinimum(0.1)
spnb_dc.setMaximum(0.4)
spnb_dc.setSingleStep(0.1)
#Port
global port_label
port_label = QLabel("Port: ")
port_layout.addWidget(port_label)
#FreqData
global flabel
flabel = QLabel("Frequency: ")
freq_layout.addWidget(flabel)
widget = QWidget()
widget.setLayout(pagelayout)
self.setCentralWidget(widget)
def find_port(self):
global thePort
global arduino
commports = serial.tools.list_ports.comports()
numPorts = len(commports)
if numPorts == 0:
port_label.setText("Port: not available")
return
if (numPorts > 1):
portNum = 0
for port in commports:
print("port number", portNum)
print(port)
portNum = portNum+1
usePort = int(input("enter port number to use 0-"+str(numPorts-1)+':'))
port.setText("yep")
else:
usePort = 0
time.sleep(1)
thePort = commports[usePort][0]
port_label.setText(str("Port: "+str(thePort)))
def start(self):
global frequency
#try:
arduino = serial.Serial(thePort, baudrate=9600, timeout=2)
time.sleep(2)
frequency = spnb_f.value()
flabel.setText(str("Frequency: "+str(frequency)))
print(type(frequency))
arduino.write(struct.pack('!f',frequency))
#except:
flabel.setText("Frequency: error. Port not connected or unavailable.")
def stop(self):
self.stacklayout.setCurrentIndex(1)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()