Inhoudsopgave:

Vingerposities meten op een viool met ESP32 - Ajarnpa
Vingerposities meten op een viool met ESP32 - Ajarnpa

Video: Vingerposities meten op een viool met ESP32 - Ajarnpa

Video: Vingerposities meten op een viool met ESP32 - Ajarnpa
Video: Ideale handpositie en vingerpositie voor piano spelen. Belangrijke Piano Tips! 2024, November
Anonim
Vingerposities meten op een viool met ESP32
Vingerposities meten op een viool met ESP32
Vingerposities meten op een viool met ESP32
Vingerposities meten op een viool met ESP32

Als violist wilde ik altijd een app of tool die me heel precies de positie van mijn vingers op de viool kon laten zien. Met dit project heb ik geprobeerd dit te bouwen. Hoewel dit een prototype is en je nog veel functies kunt toevoegen.

Ik heb ook geprobeerd de ESP32 en de rPI te scheiden en zo heb ik de ESP32 draadloos gegevens naar de rPi laten sturen. Dat is waarschijnlijk het moeilijkste aan dit project.

Het is ook erg belangrijk dat aan het einde van dit project niets op uw computer wordt opgeslagen, maar het is ofwel op de rPI of ESP32.

Stap 1: Materialen en gereedschappen

Materialen en gereedschappen
Materialen en gereedschappen

Voordat we ingaan op de details van het bouwen van dit project, hebben we een paar dingen nodig.

  1. 4x Lineaire Softpot: Lineaire Potentiometers om de positie van een vinger te meten (een viool heeft 4 snaren)
  2. ESP32: Een ESP32-module om de gegevens van de lineaire softpots te lezen.
  3. een 4/4 viool: een viool om de lineaire softpots bovenop te plaatsen.
  4. een Raspberry Pi met een SD-kaart: een raspberry pi die onze database en website zal opslaan.
  5. 10k potmeter: een potmeter voor de helderheid van het LCD
  6. LCD-scherm: een LCD-scherm om te tonen aan de ip-adressen van de rPi
  7. Soldeerset: om alle elementen aan elkaar te solderen
  8. Male-to-male draden en male-to-female draden: Kabels voor het aansluiten van alle elementen
  9. Micro-USB-kabel: voor het voeden van de ESP32

Stap 2: De Softpots aansluiten op de ESP32

De Softpots aansluiten op de ESP32
De Softpots aansluiten op de ESP32

Allereerst moeten we onze softpots aansluiten op de esp32. We verbinden de linker en rechter pinnen respectievelijk met de 5V en GND. We verbinden de middelste pin met een analoge pin op de ESP32. Ook moeten we de middelste pin aansluiten met een weerstand van 10k ohm en deze aansluiten op de GND. Dit is zodat onze uitvoer van de softpots geen willekeurige waarde retourneert.

Vervolgens verbinden we de ESP32 met de micro-usb-kabel met onze pc zodat we er code naar kunnen uploaden. We zullen de Arduino IDE gebruiken voor het programmeren van de ESP32. Maar eerst moeten we de Arduino-kern voor de ESP32 installeren, zodat we ernaar kunnen uploaden. Dit kan hier.

Dan kunnen we beginnen met het schrijven van code.

Eerst moeten we onze pinnen toewijzen waarop we onze middelste pin van de softpots hebben aangesloten.

const int SOFT_POT_PIN1 = 34;

const int SOFT_POT_PIN2 = 35;

const int SOFT_POT_PIN3 = 32;

const int SOFT_POT_PIN4 = 33;

ongetekende lange onTime;

ongetekende lange softPotTime;

Dan kunnen we onze pinnen opzetten. En we moeten onze seriële monitor en onze tijd beginnen.

ongeldige setup() {

onTime = millis();

Serieel.begin(115200);

Serial.println("Programma start");

pinMode (SOFT_POT_PIN1, INPUT);

pinMode (SOFT_POT_PIN2, INPUT);

pinMode (SOFT_POT_PIN3, INPUT);

pinMode (SOFT_POT_PIN4, INPUT); }

void getdata(byte pdata) {

// Lees de ADC-waarde van de zachte pot in

Dan moeten we onze pinnen lezen, zodat we onze gegevens kunnen ontvangen.

int softPotADC1 = analoog lezen (SOFT_POT_PIN1);

nt softPotADC2 = analoog lezen (SOFT_POT_PIN2);

int softPotADC3 = analoog lezen (SOFT_POT_PIN3);

int softPotADC4 = analoog lezen (SOFT_POT_PIN4);

Vervolgens plaatsen we de waarden in een lijst, zodat we deze later gemakkelijk kunnen uitvoeren.

voor (int i=0; i < 4; i++){

int Namen = {softPotADC1, softPotADC2, softPotADC3, softPotADC4};

int softpot = Namen;

if (softpot > 10){

pdata[0] = ik;

pdata[1] = softpot;

pdata[2] = millis();

} } }

}

Stap 3: De ESP32 en de RPI draadloos verbinden

Voor het draadloos verbinden van de ESP32 en RPI gebruiken we een bibliotheek genaamd websocket. Om deze bibliotheek te installeren, kunnen we de bestanden hier ophalen. We zullen wat code in de bestanden zelf moeten wijzigen om deze bibliotheek voor de ESP32 te gebruiken.

We zullen de MD5.c en MD5.h moeten wijzigen.

  • MD5Init naar MD5InitXXX
  • MD5Update naar MD5UpdateXXX
  • MD5Final naar MD5FinalXXX

We zullen ook de avr/io.h-regels in de sha1-bestanden moeten verwijderen.

Vervolgens kunnen we de bibliotheek per schets toevoegen aan onze Arduino IDE> bibliotheek opnemen>. ZIP-bibliotheek toevoegen en dan kunnen we uw bibliotheek in een zipbestand selecteren.

Daarna kunnen we beginnen met het schrijven van onze code.

Eerst voor de ESP32:

Inclusief onze bibliotheek

#include #include

Opnieuw onze pinnen toewijzen.

const int SOFT_POT_PIN1 = 34;

const int SOFT_POT_PIN2 = 35;

const int SOFT_POT_PIN3 = 32;

const int SOFT_POT_PIN4 = 33;

Toewijzen van onze wifi-server

WiFiServer-server (80);

Onze websocket-server starten

WebSocketServer webSocketServer;

Toewijzen van onze SSID en wachtwoord van uw wifi

const char* ssid = "uw wifi SSID";

const char* wachtwoord = "uw wifi-wachtwoord";

ongeldige setup() {

Uw seriële monitor instellen

Serieel.begin(115200);

Je softpots instellen

pinMode (SOFT_POT_PIN1, INPUT);

pinMode (SOFT_POT_PIN2, INPUT);

pinMode (SOFT_POT_PIN3, INPUT);

pinMode (SOFT_POT_PIN4, INPUT);

Onze wifi starten en ermee verbinden

WiFi.begin(ssid, wachtwoord);

while (WiFi.status() != WL_CONNECTED) {

vertraging (1000);

Serial.println("Verbinding maken met wifi.."); }

Serial.println("Verbonden met het wifi-netwerk");

Serial.println(WiFi.localIP());

server.begin(); vertraging (100); }

void getdata(char *pdata) {

Uw gegevens lezen

// Lees de ADC-waarde van de zachte pot in

int softPotADC1 = analoog lezen (SOFT_POT_PIN1);

int softPotADC2 = analoog lezen (SOFT_POT_PIN2);

int softPotADC3 = analoog lezen (SOFT_POT_PIN3);

int softPotADC4 = analoog lezen (SOFT_POT_PIN4);

De gegevens in een lijst plaatsen en converteren naar hexadecimaal.

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

}

lege lus() {

Uw klant koppelen (de rPI)

WiFiClient-client = server.beschikbaar();

if (client.verbonden()) {

vertraging(10);

if (webSocketServer.handshake(client)) {

Serial.println ("Cliënt verbonden");

Gegevens verzenden en ontvangen.

while (client.connected()) {

char-gegevens[30];

gegevens ophalen (gegevens);

Serial.println(gegevens);

webSocketServer.sendData(gegevens);

vertraging(10); // Vertraging nodig voor het correct ontvangen van de gegevens}

Serial.println ("De verbinding met de client is verbroken");

vertraging (100); }

anders {

Serial.println("shitsfuckedyo");

} } }

Dan voor de rPI in python:

Onze bibliotheken importeren

import websocket import tijd

Een globale variabele toewijzen i

ik = 0

Maximaal 200 berichten instellen die we kunnen ontvangen

aantalBerichten = 200

klasse Websocket():

def _init_(zelf):

Onze websocket initialiseren en verbinden met onze ESP32

zelf.ws = websocket. WebSocket()

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

Onze gegevens ontvangen

zeker werk (mijzelf):

zelf.ws.send("bericht nr: 0")

resultaat = self.ws.recv() time.sleep(0.5) return resultaat

Sluit de websocket na ontvangst van alles

def dicht (zelf):

zelf.ws.close()

Stap 4: Uw website en database verbinden

Wat betreft het verbinden van onze database en website, moet u eerst uw database op de pi maken door mariadb te installeren: sudo apt install mariadb.

Dan kun je er toegang toe krijgen door te doen: sudo mariadb.

Dan moet u ook uw website maken. Je kunt dit doen zoals je wilt, maar je moet Flask gebruiken en je moet een formulier in je HTML hebben om je gegevens te stoppen en te starten.

Vervolgens kunt u deze code invoegen om uw database en uw website te verbinden (zowel uw website als database moeten beide op uw pi staan, dit kan via het tabblad Deployment in de instellingen van pycharm)

van flaskext.mysql importeer MySQL

app.config["MYSQL_DATABASE_HOST"] = "lokale host"

app.config["MYSQL_DATABASE_DB"] = "uw databasenaam"

app.config["MYSQL_DATABASE_USER"] = "uw databasegebruiker"

app.config["MYSQL_DATABASE_PASSWORD"] = "uw databasewachtwoord"

Functie om gegevens uit onze database te halen.

def get_data(sql, params=Geen):

conn = mysql.connect()

cursor = conn.cursor()

print("gegevens ophalen")

proberen:

afdrukken (sql)

cursor.execute(sql, params)

uitzondering Uitzondering als e:

print(e)

retourneer False

resultaat = cursor.fetchall()

gegevens =

voor rij in resultaat:

data.append(lijst(rij))

cursor.close()

verbind.close()

gegevens retourneren

Functie voor het invoegen van gegevens in onze database

def set_data(sql, params=Geen):

conn = mysql.connect()

cursor = conn.cursor()

proberen:

log.debug(sql)

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

log.debug("SQL uitgevoerd")

uitzondering Uitzondering als e:

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

retourneer False

cursor.close()

verbind.close()

retourneer True

We zullen ook onze applicatie moeten gebruiken, zodat u andere dingen kunt doen terwijl u aan het opnemen bent.

klasse ThreadedTask (threading. Thread):

def _init_(zelf,):

Draad opzetten

threading. Thread._init_(zelf)

Een lijst maken voor het bewaren van al uw ontvangen gegevens

zelf.data_all =

def uitvoeren (zelf):

tijd.slaap(5)

Importeer uw eigen python-code waar u de gegevens ontvangt

ontvangst_websocket importeren

Ontvang uw gegevens

w = ontvang_websocket. Websocket()

Voeg uw gegevens toe aan uw lijst en print deze uit.

voor i binnen bereik (0, 200):

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

print(self.data_all)

taak = ThreadedTask()

Dan kun je task.run() doen om je Thread te starten en gegevens te ontvangen.

Stap 5: Alles met elkaar verbinden

Alles met elkaar verbinden
Alles met elkaar verbinden

Om uw website vanaf uw Pi te laten draaien, moet u een service gebruiken:

[Unit]Description=uWSGI-instantie om de webinterface van project1 te bedienen

Na=netwerk.doel

BindsTo=mysqld.service

Na=mysqld.service

[Onderhoud]

Wijzig naar uw gebruiker

Gebruiker=pi

Groep=www-gegevens

Hier moet u uw map van uw Flask-bestand invoeren

WorkingDirectory=/home/pi/project1/web

Directory van uw ini-bestand die u later kunt vinden.

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

[Installeren]

WantedBy=multi-user.target

uwsgi-flask.ini die u in de map moet plaatsen die u hierboven in ExecStart hebt opgegeven

[uwsgi]module = web:app virtualenv = /home/pi/project1/env

master = echte processen = 5

plug-ins = python3

socket = project1.sock chmod-socket = 660 vacuüm = true

die-op-termijn = waar

Nu kunt u uw gegevens uitlezen en weergeven op uw website.

Stap 6: Extra: LCD-scherm aansluiten

Extra: LCD-scherm aansluiten
Extra: LCD-scherm aansluiten
Extra: LCD-scherm aansluiten
Extra: LCD-scherm aansluiten
Extra: LCD-scherm aansluiten
Extra: LCD-scherm aansluiten

We kunnen een LCD-scherm aansluiten zodat we het ip-adres van onze Pi kunnen tonen voor onze website.

importeer RPi. GPIO als GPIOimporttijd

commando's importeren

GPIO.opschonen()

D0 = 22

D1 = 5

D2 = 6

D3 = 13

D4 = 19

D5 = 26

D6 = 20

D7 = 21

lijst = [22, 5, 6, 13, 19, 26, 20, 21]

E = 24

RS = 23

klasse Scherm:

def _init_(zelf):

GPIO.setmode(GPIO. BCM)

zelf.setup()

#Functieset self.stuur_instructie(0x3f) #Display self.stuur_instructie(0x0c) #On + cursor self.stuur_instructie(0x01) @staticmethod def setup(): GPIO.setup(list, GPIO. OUT) GPIO.setup([E, RS], GPIO. OUT)

def stuur_instructie(zelf, byte):

GPIO.uitgang (E, GPIO. HOOG)

GPIO.output (RS, GPIO. LOW)

zelf.set_GPIO_bits(byte)

tijd.slaap(0.005)

GPIO.output (E, GPIO. LOW)

def stuur_teken(zelf, char):

temp = orde (char)

GPIO.uitgang (E, GPIO. HOOG)

GPIO.uitgang (RS, GPIO. HOOG)

zelf.set_GPIO_bits(temp)

tijd.slaap(0.005)

GPIO.output (E, GPIO. LOW)

def set_GPIO_bits (zelf, byte):

voor i binnen bereik (0, 8):

if (byte & (2**i)) == 0:

GPIO.output(lijst, GPIO. LOW)

anders:

GPIO.output(lijst, GPIO. HIGH)

def hoofd():

s = Scherm()

teken = "Lokaal IP-adres:"

voor letter in teken:

s.stuur_teken(letter)

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

print(teken2)

s.stuur_instructie(0xc0)

voor letter2 in teken2:

s.stuur_teken(letter2)

if _name_ == '_main_': #Programma vanaf hier

proberen:

hoofd()

behalve KeyboardInterrupt:

doorgang

Dan kunnen we een service maken om het LCD-scherm te starten bij het opstarten.

Aanbevolen: