ESP32とMicroPythonのADCでジョイスティックの位置をPCのPyQtGraphに表示する
2020/07/11 categories:ESP32| tags:ESP32|MicroPython|
MicroPythonを入れたESP32でAD変換を使ってみるためにジョイスティックの位置を読み取ってみました。シリアル通信でPCに送られてきた文字列をただ表示するだけじゃ面白くないのでPyQtGraphのグラフに表示してみました。
マイコンからの受信データの確認
AD変換した値をシリアル通信で送信するプログラムを作成しました。プログラムはAD変換の設定をした後に値を送り続けるという単純なプログラムです。VS codeのステータスバーのRunをクリックするとデータが送られてきてターミナルに表示されました。このデータを処理してパソコン側でグラフとして表示してみます。
パソコン側でのグラフ表示
以前作成したPyQtGraphを使ったコードを流用して作成しました。受信した値はnumpy配列の最後のインデックスに入れていき、最初のインデックスのデータは削除することで、グラフに軌跡が残るように表示してみました。グラフの描画はPyQtのQTimerで一定間隔で行うようにしています。
self.plot_data['X'] = np.append( self.plot_data['X'][1:], float(splited[1]) )
self.plot_data['Y'] = np.append( self.plot_data['Y'][1:], float(splited[3]) )
所感
マイコン側もパソコン側もPythonでコードを書くことができるのは便利ですね。ロボットの制御とかにも使ってみたいと思います。今回作ったプログラムは表示できればよかっただけなので、PC側のソフトでデータの取りこぼしがあるかもしれません。シリアル通信についてはもう少し調べてみたいと思います。
マイコンのコード
import time
from machine import Pin, ADC
## ADC settings
adc_x = ADC(Pin(34))
adc_y = ADC(Pin(35))
adc_x.atten(ADC.ATTN_11DB)
adc_y.atten(ADC.ATTN_11DB)
while True:
x = adc_x.read()
y = adc_y.read()
print("x", x, "y", y)
time.sleep_ms(100)
パソコンのコード
## -*- coding: utf-8 -*-
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from pyqtgraph import PlotWidget
import pyqtgraph
import numpy as np
import serial
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.plot_data = { 'X':np.full(10, 0), 'Y':np.full(10, 0) }
self.resize(600, 600)
self.setStyleSheet("QMainWindow {background: 'white';}")
self.serial = serial.Serial('COM3', 115200, timeout=None)
# leyout
self.centralwidget = QtWidgets.QWidget(self)
self.setCentralWidget(self.centralwidget)
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout2 = QtWidgets.QHBoxLayout()
self.verticalLayout.addLayout(self.horizontalLayout)
self.verticalLayout.addLayout(self.horizontalLayout2)
# pot widget
self.plotwidget = PlotWidget(self)
self.plotwidget.setBackground("#FFFFFFFF")
plotitem = self.plotwidget.plotItem
plotitem.setLabels(bottom='X', left='Y')
plotitem.getAxis('bottom').setPen( pyqtgraph.mkPen(color='#000000') )
plotitem.getAxis('left').setPen( pyqtgraph.mkPen(color='#000000') )
plotitem.setRange(xRange = (0, 4095), yRange = (0, 4095), padding = 0)
# leyout
self.horizontalLayout.addWidget(self.plotwidget)
# timer
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.update_data)
self.timer.start(50)
def update_data(self):
# stop timer
self.timer.stop()
# clear
self.plotwidget.clear()
# get serial
line = self.serial.readline()
splited = line.split()
self.plot_data['X'] = np.append( self.plot_data['X'][1:], float(splited[1]) )
self.plot_data['Y'] = np.append( self.plot_data['Y'][1:], float(splited[3]) )
# set data
self.plotwidget.addItem(
pyqtgraph.PlotDataItem(
x=self.plot_data['X'], y=self.plot_data['Y'],
pen=pyqtgraph.mkPen(color='#000000', width=10), antialias=True
)
)
print(self.plot_data['X'], self.plot_data['Y'])
# start timer
self.timer.start(50)
def main():
app = QtWidgets.QApplication(sys.argv)
mainwindow = MainWindow(None)
mainwindow.show()
app.exec()
if __name__ == '__main__':
main()