สารบัญ:

การวัดตำแหน่งนิ้วบนไวโอลินด้วย ESP32: 6 ขั้นตอน
การวัดตำแหน่งนิ้วบนไวโอลินด้วย ESP32: 6 ขั้นตอน

วีดีโอ: การวัดตำแหน่งนิ้วบนไวโอลินด้วย ESP32: 6 ขั้นตอน

วีดีโอ: การวัดตำแหน่งนิ้วบนไวโอลินด้วย ESP32: 6 ขั้นตอน
วีดีโอ: Live 19-03-2021 กลุ่ม Arduino Thailand ทักษะไม่มีขาย อยากได้ต้องลงมือทำ 2024, กรกฎาคม
Anonim
การวัดตำแหน่งนิ้วบนไวโอลินด้วย ESP32
การวัดตำแหน่งนิ้วบนไวโอลินด้วย ESP32
การวัดตำแหน่งนิ้วบนไวโอลินด้วย ESP32
การวัดตำแหน่งนิ้วบนไวโอลินด้วย ESP32

ในฐานะนักไวโอลิน ฉันต้องการแอปหรือเครื่องมือที่สามารถแสดงตำแหน่งนิ้วของฉันบนไวโอลินได้อย่างแม่นยำมาก ด้วยโครงการนี้ ฉันพยายามสร้างสิ่งนี้ แม้ว่านี่จะเป็นเครื่องต้นแบบและคุณยังสามารถเพิ่มคุณสมบัติมากมายได้

ฉันยังพยายามแยก ESP32 และ rPI ออกจากกัน ดังนั้นฉันจึงทำให้ ESP32 ส่งข้อมูลแบบไร้สายไปยัง rPi ซึ่งอาจเป็นสิ่งที่ยากที่สุดเกี่ยวกับโครงการนี้

เป็นสิ่งสำคัญมากที่เมื่อสิ้นสุดโปรเจ็กต์นี้ จะไม่มีการจัดเก็บสิ่งใดในคอมพิวเตอร์ของคุณ แต่จะอยู่ใน rPI หรือ ESP32

ขั้นตอนที่ 1: วัสดุและเครื่องมือ

วัสดุและเครื่องมือ
วัสดุและเครื่องมือ

ก่อนที่จะเจาะลึกถึงรายละเอียดเฉพาะของการสร้างโครงการนี้ เราจำเป็นต้องมีบางสิ่งก่อน

  1. 4x Linear Softpot: โพเทนชิโอมิเตอร์เชิงเส้นเพื่อวัดตำแหน่งของนิ้ว (ไวโอลินมี 4 สาย)
  2. ESP32: โมดูล ESP32 สำหรับอ่านข้อมูลจากซอฟต์พอตเชิงเส้น
  3. ไวโอลิน 4/4: ไวโอลินสำหรับวางซอฟต์พอตเชิงเส้นไว้ด้านบน
  4. Raspberry Pi พร้อมการ์ด SD: raspberry pi ซึ่งจะจัดเก็บฐานข้อมูลและเว็บไซต์ของเรา
  5. โพเทนชิออมิเตอร์ 10k: โพเทนชิออมิเตอร์สำหรับความสว่างของ LCD
  6. หน้าจอ LCD: หน้าจอ LCD เพื่อแสดงที่อยู่ IP ของ rPi
  7. ชุดบัดกรี: สำหรับการบัดกรีองค์ประกอบทั้งหมดเข้าด้วยกัน
  8. สายตัวผู้กับตัวผู้และสายตัวผู้กับตัวเมีย: สายเคเบิลสำหรับเชื่อมต่อองค์ประกอบทั้งหมด
  9. สาย Micro USB: สำหรับจ่ายไฟให้กับ ESP32

ขั้นตอนที่ 2: เชื่อมต่อ Softpots กับ ESP32

การเชื่อมต่อ Softpots กับ ESP32
การเชื่อมต่อ Softpots กับ ESP32

ก่อนอื่นเราต้องเชื่อมต่อ softpots ของเรากับ esp32 เราเชื่อมต่อพินซ้ายและขวากับ 5V และ GND ตามลำดับ เราเชื่อมต่อพินกลางกับพินอะนาล็อกบน ESP32 เรายังต้องเชื่อมต่อพินกลางด้วยความต้านทาน 10k ohm และเชื่อมต่อสิ่งนี้กับ GND เพื่อให้ผลลัพธ์ของ softpots ของเราไม่คืนค่าแบบสุ่ม

จากนั้นเราเชื่อมต่อ ESP32 ด้วยสายไมโคร USB กับพีซีของเรา เพื่อให้เราสามารถอัปโหลดโค้ดไปยังเครื่องได้ เราจะใช้ Arduino IDE เพื่อตั้งโปรแกรม ESP32 แต่ก่อนอื่นเราต้องติดตั้ง Arduino core สำหรับ ESP32 เพื่อให้เราสามารถอัปโหลดได้ สามารถทำได้ที่นี่

จากนั้นเราก็เริ่มเขียนโค้ดได้เลย

อันดับแรก เราต้องกำหนดพินของเราที่เราเชื่อมต่อพินกลางของซอฟต์พอต

const int SOFT_POT_PIN1 = 34;

const int SOFT_POT_PIN2 = 35;

const int SOFT_POT_PIN3 = 32;

const int SOFT_POT_PIN4 = 33;

onTime ยาวที่ไม่ได้ลงนาม;

softPotTime แบบยาวที่ไม่ได้ลงนาม

จากนั้นเราก็สามารถตั้งค่าพินของเราได้ และเราจำเป็นต้องเริ่มการตรวจสอบอนุกรมและเวลาของเรา

การตั้งค่าเป็นโมฆะ () {

onTime = มิลลิวินาที ();

Serial.begin(115200);

Serial.println("โปรแกรมเริ่มต้น");

โหมดพิน (SOFT_POT_PIN1, INPUT);

โหมดพิน (SOFT_POT_PIN2, INPUT);

โหมดพิน (SOFT_POT_PIN3, INPUT);

โหมดพิน (SOFT_POT_PIN4, INPUT); }

เป็นโมฆะ getdata (ไบต์ pdata ) {

// อ่านค่า ADC ของหม้อนุ่ม

จากนั้นเราต้องอ่านพินของเราเพื่อรับข้อมูลของเรา

int softPotADC1 = analogRead (SOFT_POT_PIN1);

nt softPotADC2 = analogRead (SOFT_POT_PIN2);

int softPotADC3 = analogRead (SOFT_POT_PIN3);

int softPotADC4 = analogRead (SOFT_POT_PIN4);

จากนั้นเราใส่ค่าในรายการเพื่อให้เราสามารถส่งออกได้อย่างง่ายดายในภายหลัง

สำหรับ (int i=0; i <4; i++){

ชื่อ int = {softPotADC1, softPotADC2, softPotADC3, softPotADC4};

int softpot = ชื่อ;

ถ้า (softpot > 10){

pdata[0] = ผม;

pdata[1] = ซอฟต์พอท;

pdata[2] = มิลลิวินาที ();

} } }

}

ขั้นตอนที่ 3: เชื่อมต่อ ESP32 และ RPI แบบไร้สาย

สำหรับการเชื่อมต่อ ESP32 และ RPI แบบไร้สาย เราจะใช้ไลบรารี่ที่เรียกว่า websocket ในการติดตั้งไลบรารีนี้ เราสามารถรับไฟล์ได้ที่นี่ เราจะต้องเปลี่ยนโค้ดบางตัวในไฟล์นั้นเองเพื่อใช้ไลบรารี่นี้สำหรับ ESP32

เราจะต้องเปลี่ยน MD5.c และ MD5.h.

  • MD5Init เป็น MD5InitXXX
  • MD5อัปเดตเป็น MD5อัปเดตXXX
  • MD5Final ถึง MD5FinalXXX

เราจะต้องลบบรรทัด avr/io.h ในไฟล์ sha1 ด้วย

จากนั้นเราสามารถเพิ่มไลบรารีลงใน Arduino IDE ของเราได้ด้วยการสเก็ตช์ > รวมไลบรารี > เพิ่มไลบรารี. ZIP จากนั้นเราสามารถเลือกไลบรารีของคุณในไฟล์ zip

หลังจากนั้นเราสามารถเริ่มเขียนโค้ดของเราได้

ครั้งแรกสำหรับ ESP32:

รวมถึงห้องสมุดของเรา

#รวม #รวม

กำหนดหมุดของเราอีกครั้ง

const int SOFT_POT_PIN1 = 34;

const int SOFT_POT_PIN2 = 35;

const int SOFT_POT_PIN3 = 32;

const int SOFT_POT_PIN4 = 33;

กำหนดเซิร์ฟเวอร์ wifi ของเรา

เซิร์ฟเวอร์ WiFiServer(80);

การเริ่มต้นเซิร์ฟเวอร์ websocket ของเรา

WebSocketServer webSocketServer;

กำหนด SSID และรหัสผ่าน wifi ของคุณ

const char* ssid = "SSID ไร้สายของคุณ";

const char* password = "รหัสผ่าน wifi ของคุณ";

การตั้งค่าเป็นโมฆะ () {

การตั้งค่าจอภาพอนุกรมของคุณ

Serial.begin(115200);

การตั้งค่าซอฟต์พอตของคุณ

โหมดพิน (SOFT_POT_PIN1, INPUT);

โหมดพิน (SOFT_POT_PIN2, INPUT);

โหมดพิน (SOFT_POT_PIN3, INPUT);

โหมดพิน (SOFT_POT_PIN4, INPUT);

กำลังเริ่ม wifi ของเราและเชื่อมต่อกับมัน

WiFi.begin(ssid, รหัสผ่าน);

ในขณะที่ (WiFi.status () != WL_CONNECTED) {

ล่าช้า (1000);

Serial.println("กำลังเชื่อมต่อกับ WiFi.."); }

Serial.println("เชื่อมต่อกับเครือข่าย WiFi แล้ว");

Serial.println(WiFi.localIP());

เซิร์ฟเวอร์.begin(); ล่าช้า (100); }

เป็นโมฆะ getdata (ถ่าน * pdata) {

การอ่านข้อมูลของคุณ

// อ่านค่า ADC ของหม้อนุ่ม

int softPotADC1 = analogRead (SOFT_POT_PIN1);

int softPotADC2 = analogRead (SOFT_POT_PIN2);

int softPotADC3 = analogRead (SOFT_POT_PIN3);

int softPotADC4 = analogRead (SOFT_POT_PIN4);

การวางข้อมูลในรายการและแปลงเป็นเลขฐานสิบหก

sprintf(pdata, "%x, %x, %x, %x, %x", softPotADC1, softPotADC2, softPotADC3, softPotADC4, millis());

}

วงเป็นโมฆะ () {

การเชื่อมต่อไคลเอ็นต์ของคุณ (rPI)

ไคลเอนต์ WiFiClient = server.available ();

ถ้า (ไคลเอนต์เชื่อมต่อ ()) {

ล่าช้า(10);

ถ้า (webSocketServer.handshake (ไคลเอนต์)) {

Serial.println("ลูกค้าเชื่อมต่อแล้ว");

การส่งและรับข้อมูล

ในขณะที่ (ไคลเอนต์เชื่อมต่อ ()) {

ข้อมูลถ่าน[30];

getdata(ข้อมูล);

Serial.println (ข้อมูล);

webSocketServer.sendData (ข้อมูล);

ล่าช้า(10); // ความล่าช้าที่จำเป็นสำหรับการรับข้อมูลอย่างถูกต้อง }

Serial.println("ไคลเอ็นต์ถูกตัดการเชื่อมต่อ");

ล่าช้า (100); }

อื่น {

Serial.println("shitsfuckedyo");

} } }

จากนั้นสำหรับ rPI ใน python:

การนำเข้าห้องสมุดของเรา

นำเข้าเวลา websocketimport

การกำหนดตัวแปร globale i

ผม = 0

การตั้งค่าข้อความสูงสุด 200 ข้อความที่เราสามารถรับได้

nrOfMessages = 200

คลาส Websocket():

def _init_ (ตัวเอง):

กำลังเริ่มต้น websocket ของเราและเชื่อมต่อกับ ESP32. ของเรา

self.ws = websocket. WebSocket ()

self.ws.connect("ws://172.30.248.48/")

การรับข้อมูลของเรา

def ทำงาน (ตัวเอง):

self.ws.send("หมายเลขข้อความ: 0")

ผลลัพธ์ = self.ws.recv() time.sleep(0.5) ส่งคืนผลลัพธ์

ปิด websocket หลังได้รับของครบ

def ปิด (ตัวเอง):

self.ws.close()

ขั้นตอนที่ 4: เชื่อมต่อเว็บไซต์และฐานข้อมูลของคุณ

สำหรับการเชื่อมต่อฐานข้อมูลและเว็บไซต์ของเรา ก่อนอื่นคุณต้องสร้างฐานข้อมูลของคุณบน pi โดยติดตั้ง mariadb: sudo apt install mariadb

จากนั้นคุณสามารถเข้าถึงได้โดยทำ: sudo mariadb.

จากนั้นคุณจะต้องสร้างเว็บไซต์ของคุณด้วย คุณสามารถทำเช่นนี้ได้ตามที่คุณต้องการ แต่คุณต้องใช้ Flask และคุณต้องมีแบบฟอร์มใน HTML ของคุณเพื่อหยุดและเริ่มต้นข้อมูลของคุณ

จากนั้นคุณสามารถแทรกรหัสนี้เพื่อเชื่อมต่อฐานข้อมูลและเว็บไซต์ของคุณ (ทั้งเว็บไซต์และฐานข้อมูลของคุณต้องอยู่ใน pi ของคุณ ซึ่งสามารถทำได้โดยใช้แท็บการปรับใช้ในการตั้งค่าของ pycharm)

จาก flaskext.mysql นำเข้า MySQL

app.config["MYSQL_DATABASE_HOST"] = "localhost"

app.config["MYSQL_DATABASE_DB"] = "ชื่อฐานข้อมูลของคุณ"

app.config["MYSQL_DATABASE_USER"] = "ผู้ใช้ฐานข้อมูลของคุณ"

app.config["MYSQL_DATABASE_PASSWORD"] = "รหัสผ่านฐานข้อมูลของคุณ"

ฟังก์ชันสำหรับดึงข้อมูลออกจากฐานข้อมูลของเรา

def get_data(sql, params=None):

conn = mysql.connect()

เคอร์เซอร์ = conn.cursor ()

พิมพ์ ("รับข้อมูล")

ลอง:

พิมพ์ (sql)

cursor.execute (sql, params)

ยกเว้นข้อยกเว้นเป็น e:

พิมพ์ (จ)

กลับเท็จ

ผลลัพธ์ = cursor.fetchall()

ข้อมูล =

สำหรับแถวผลลัพธ์:

data.append(รายการ(แถว))

เคอร์เซอร์.close()

conn.close()

ส่งคืนข้อมูล

ฟังก์ชันสำหรับแทรกข้อมูลลงในฐานข้อมูลของเรา

def set_data(sql, params=None):

conn = mysql.connect()

เคอร์เซอร์ = conn.cursor ()

ลอง:

log.debug(sql)

cursor.execute(sql, params) conn.commit()

log.debug("SQL uitgevoerd")

ยกเว้นข้อยกเว้นเป็น e:

log.exception("Fout bij uitvoeren van sql: {0})".format(e))

กลับเท็จ

เคอร์เซอร์.close()

conn.close()

กลับ True

เราจะต้องเธรดแอปพลิเคชันของเราด้วยเพื่อให้คุณสามารถทำสิ่งอื่น ๆ ได้ในขณะที่คุณกำลังบันทึก

คลาส ThreadedTask(threading. Thread):

def _init_(ตัวเอง,):

ตั้งกระทู้

threading. Thread._init_(ตัวเอง)

การสร้างรายการสำหรับเก็บข้อมูลที่ได้รับทั้งหมดของคุณ

self.data_all =

def รัน (ตัวเอง):

เวลานอน(5)

นำเข้ารหัสหลามของคุณเองที่คุณรับข้อมูล

นำเข้ารับ_websocket

รับข้อมูลของคุณ

w = รับ_websocket. Websocket()

ผนวกข้อมูลของคุณในรายการของคุณและพิมพ์ออกมา

สำหรับฉันอยู่ในช่วง (0, 200):

self.data_all.append(w.work().split(", "))

พิมพ์ (self.data_all)

งาน = ThreadedTask()

จากนั้น คุณสามารถทำ task.run() เพื่อเริ่มเธรดของคุณและเริ่มรับข้อมูล

ขั้นตอนที่ 5: เชื่อมต่อทุกอย่างเข้าด้วยกัน

เชื่อมต่อทุกอย่างเข้าด้วยกัน
เชื่อมต่อทุกอย่างเข้าด้วยกัน

สำหรับการเรียกใช้เว็บไซต์ของคุณจาก Pi คุณต้องใช้บริการ:

[หน่วย]Description=uWSGI อินสแตนซ์เพื่อให้บริการเว็บอินเตอร์เฟสของโปรเจ็กต์1

After=network.target

BindsTo=mysqld.service

After=mysqld.service

[บริการ]

เปลี่ยนเป็นผู้ใช้ของคุณ

ผู้ใช้=pi

Group=www-data

ที่นี่คุณต้องป้อนไดเร็กทอรีของไฟล์ Flask ของคุณ

WorkingDirectory=/home/pi/project1/web

ไดเร็กทอรีของไฟล์ ini ของคุณที่สามารถพบได้ในภายหลัง

ExecStart=/usr/bin/uwsgi --ini /home/pi/project1/conf/uwsgi-flask.ini

[ติดตั้ง]

WantedBy=multi-user.target

uwsgi-flask.ini ที่คุณต้องวางในไดเร็กทอรีที่คุณระบุไว้ใน ExecStart ด้านบน

[uwsgi] โมดูล = เว็บ: แอพ virtualenv = /home/pi/project1/env

มาสเตอร์ = กระบวนการจริง = 5

ปลั๊กอิน = python3

socket = project1.sock chmod-socket = 660 สุญญากาศ = true

die-on-term = จริง

ตอนนี้คุณสามารถอ่านข้อมูลของคุณและแสดงบนเว็บไซต์ของคุณได้

ขั้นตอนที่ 6: พิเศษ: การเชื่อมต่อหน้าจอ LCD

พิเศษ: การเชื่อมต่อหน้าจอ LCD
พิเศษ: การเชื่อมต่อหน้าจอ LCD
พิเศษ: การเชื่อมต่อหน้าจอ LCD
พิเศษ: การเชื่อมต่อหน้าจอ LCD
พิเศษ: การเชื่อมต่อหน้าจอ LCD
พิเศษ: การเชื่อมต่อหน้าจอ LCD

เราสามารถเชื่อมต่อหน้าจอ LCD เพื่อให้เราสามารถแสดงที่อยู่ IP ของ Pi สำหรับเว็บไซต์ของเรา

นำเข้า RPi. GPIO เป็น GPIOนำเข้าเวลา

คำสั่งนำเข้า

GPIO. การล้างข้อมูล ()

D0 = 22

D1 = 5

D2 = 6

D3 = 13

D4 = 19

D5 = 26

D6 = 20

D7 = 21

รายการ = [22, 5, 6, 13, 19, 26, 20, 21]

E = 24

อาร์เอส = 23

หน้าจอคลาส:

def _init_ (ตัวเอง):

GPIO.setmode(GPIO. BCM)

self.setup()

#Function set self.stuur_instructie(0x3f) #Display self.stuur_instructie(0x0c) #On + เคอร์เซอร์ self.stuur_instructie(0x01) @staticmethod def setup(): GPIO.setup(list, GPIO. OUT) GPIO.setup([E, RS], GPIO. OUT)

def stuur_instructie (ตัวเอง, ไบต์):

GPIO.output(E, GPIO.สูง)

GPIO.output(RS, GPIO.ต่ำ)

self.set_GPIO_bits (ไบต์)

เวลานอน (0.005)

GPIO.output(E, GPIO.ต่ำ)

def stuur_teken(ตัวเอง, ถ่าน):

อุณหภูมิ = ord(ถ่าน)

GPIO.output(E, GPIO.สูง)

GPIO.output(RS, GPIO.สูง)

self.set_GPIO_bits (ชั่วคราว)

เวลานอน (0.005)

GPIO.output(E, GPIO.ต่ำ)

def set_GPIO_bits (ตัวเอง, ไบต์):

สำหรับฉันอยู่ในช่วง (0, 8):

ถ้า (ไบต์ & (2**i)) == 0:

GPIO.output(รายการ, GPIO. LOW)

อื่น:

GPIO.output(รายการ, GPIO.สูง)

def หลัก ():

s = หน้าจอ ()

teken = "ที่อยู่ IP ท้องถิ่น:"

สำหรับจดหมายใน teken:

s.stuur_teken(จดหมาย)

teken2 = commands.getoutput("ip addr show wlan0 | grep -Po 'inet \K[d.]+'")

พิมพ์(teken2)

s.stuur_instructie(0xc0)

สำหรับ letter2 ใน teken2:

s.stuur_teken(letter2)

ถ้า _name_ == '_main_': #โปรแกรมเริ่มต้นจากที่นี่

ลอง:

หลัก()

ยกเว้น KeyboardInterrupt:

ผ่าน

จากนั้นเราสามารถสร้างบริการเพื่อเริ่มต้น LCD เมื่อเริ่มทำงาน

แนะนำ: