Télécommande intelligente 2 : Différence entre versions

De Wiki LOGre
Aller à : navigation, rechercher
m (Réalisation)
m (Réalisation)
Ligne 36 : Ligne 36 :
  
 
[[Fichier:RC-4.jpg|300px]]
 
[[Fichier:RC-4.jpg|300px]]
 +
 +
 +
[https://cad.onshape.com/documents/5e3930981675cbee98f7b651/w/4e11e1a1be027aee5728d2be/e/03c50577ef13f0763a9108c5 Lien Onshape]
  
 
== Câblage ==
 
== Câblage ==

Version du 15 septembre 2020 à 11:28

Langue : Français

Projet réalisé par fma38.

En cours

Présentation

Réalisation d'une nouvelle télécommande intelligente pour piloter un hexapode ou BB-8. Ce projet fait suite à ma première télécommande intelligente.

Cette fois, j'utilise des petits joysticks 3 axes à monter sur panneau. La partie électronique se fait via une carte WiPy 3.0 (à base d'ESP32), et intègre un écran OLED 1,5".

Le choix de la Wipy 3.0 s'est fait car c'est une des rares cartes à exposer toutes les pins des ADC. Car il faut savoir que lorsque le wifi est actif, l'ADC2 n'est plus utilisable ! Or, initialement, je comptais faire lire les joysticks et potentiomètres directement par l'ESP32, et sur les autres cartes, il n'y avait pas assez d'entrées. Depuis, j'ai développé un petit module monté à l'arrière des joysticks, qui permet de lire 4 ADC et 4 I/O, le tout via le bus I²C. Du coup, une carte ESP32 plus classique conviendrait. Ceci-dit, la Wipy 3.0 dispose d'un connecteur pour une antenne externe, que j'utilise, et qui permet d'étendre grandement la portée du wifi.

Cahier des charges

  • 2 joysticks analogiques 3 axes + bouton + PCB I²C
  • 2 potentiomètre linéaires
  • 4 inverseurs
  • 6 boutons poussoirs (3 momentanés, 3 bistables)
  • écran OLED 128x128 (I²C)
  • roue codeuse + click central + 4 directions + led RGB (I²C)
  • MPU6050 (I²C)
  • communication UDP (bidirectionnelle) via wifi
  • alimentation par Li-ion 18650 (chargeur intégré)

Réalisation

Le boîtier est bien sûr réalisé en impression 3D ; il est composé de 3 pièces seulement, mais nécessite une surface d'impression de 300x200mm.

RC 1.png RC 2.png RC 3.png

RC-4.jpg


Lien Onshape

Câblage

Tableau de correspondance des fils des joysticks 3 voies :

axe Z  : blanc / noir (curseur) / rouge
bouton : bleu / bleu

Câblage retenu sur la carte WiPy 3.0 :

Wipy3-pinout.png

 5 / GPIO36 / AD1_0 / P13 :
 6 / GPIO37 / AD1_1 / P14 :
 7 / GPIO38 / AD1_2 / P15 :
 8 / GPIO39 / AD1_3 / P16 :
10 / GPIO35 / AD1_7 / P17 :
11 / GPIO34 / AD1_6 / P18 :
12 / GPIO32 / AD1_4 / P19 :
13 / GPIO33 / AD1_5 / P20 : battery monitoring
15 / GPIO26 /       / P21 :
14 / GPIO25 /       / P22 :
17 / GPIO14 /       / P23 : 
39 / GPIO22 /       / P11 : i2cNavKey interruption
20 / GPIO13 /       / P10 : SCL
18 / GPIO12 /       / P9  : SDA
22 / GPIO2  /       / P8  :
38 / GPIO19 /       / P7  :
16 / GPIO27 /       / P6  :
34 / GPIO5  /       / P5  :
21 / GPIO15 /       / P4  :
24 / GPIO4  /       / P3  :
23 / GPIO0  /       / P2  : Bootloader switch
41 / GPIO1  /       / P1  : TX0 (prog)
40 / GPIO3  /       / P0  : RX0 (prog)

Soft

Exemple de code :

#include "WiFi.h"
#include "AsyncUDP.h"
#include "ArduinoJson.h"

const char *ssid = "";
const char *password = "";

AsyncUDP udp;

StaticJsonDocument<300> jsonData;

const uint8_t X = A0;
const uint8_t Y = A1;
const uint8_t Z = A2;
const uint8_t A = A3;
const uint8_t U = A7;
const uint8_t V = A6;
const uint8_t W = A4;
const uint8_t B = A5;

const uint8_t IO0 = 26;
const uint8_t IO1 = 25;


void setup()
{
    Serial.begin(115200);

    pinMode(IO0, INPUT_PULLUP);
    pinMode(IO1, INPUT_PULLUP);

    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    
    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.println("WiFi Failed");
        while (1) {
            delay(1000);
        }
    }
    
    if (udp.connect(IPAddress(192,168,0,2), 1234)) {
        Serial.println("UDP connected");
        
        udp.onPacket([](AsyncUDPPacket packet) {
            Serial.print("UDP Packet Type: ");
            Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
            Serial.print(", From: ");
            Serial.print(packet.remoteIP());
            Serial.print(":");
            Serial.print(packet.remotePort());
            Serial.print(", To: ");
            Serial.print(packet.localIP());
            Serial.print(":");
            Serial.print(packet.localPort());
            Serial.print(", Length: ");
            Serial.print(packet.length());
            Serial.print(", Data: ");
            Serial.write(packet.data(), packet.length());
            Serial.println();
            
            // Reply to the client
            //packet.printf("Got %u bytes of data", packet.length());
        });
        
        // Send unicast
        udp.print("Hello Server!");
    }

}

void loop()
{
    String s;

    jsonData["timeStamp"] = millis();

    jsonData["analog"]["X"] = map(analogRead(X), 0, 4095, 0, 255);
    jsonData["analog"]["Y"] = map(analogRead(Y), 0, 4095, 0, 255);
    jsonData["analog"]["Z"] = map(analogRead(Z), 0, 4095, 0, 255);
    jsonData["analog"]["A"] = map(analogRead(A), 0, 4095, 0, 255);
    jsonData["analog"]["U"] = map(analogRead(U), 0, 4095, 0, 255);
    jsonData["analog"]["V"] = map(analogRead(V), 0, 4095, 0, 255);
    jsonData["analog"]["W"] = map(analogRead(W), 0, 4095, 0, 255);
    jsonData["analog"]["B"] = map(analogRead(B), 0, 4095, 0, 255);

    jsonData["digital"]["D0"] = digitalRead(IO0);
    jsonData["digital"]["D1"] = digitalRead(IO1);

    serializeJson(jsonData, s);
    serializeJsonPretty(jsonData, Serial);
    Serial.println();

    udp.print(s.c_str());

    delay(100);
}

Annexes

Programmation de la WiPy 3.0

Cette carte nécessite une tension d'alimentation de 3,5V minimum, mais les I/O doivent être en 3,3V. Du coup, un câble FTDI 5V risque de griller les I/O, et un câble 3,3V ne pourra pas alimenter la carte. La solution est d'utiliser ce genre de module FTDI. En effet, on peut sélectionner la tension des I/O à 3,3V, et disposer quand même d'une alimentation 5V ; l'astuce consiste à ne pas utiliser la pin Vcc sur le connecteur arrière, qui sera donc à 3,3V, mais la pin marquée 5V, sur le connecteur latéral.

La WiPy 3.0, contrairement à la plupart de ses équivalentes, n'a pas de port USB intégré. La programmation se fait via TX0/RX0, une fois en mode bootloader. Pour ça, il faut démarrer l'ESP32 avec la pin GPIO0 à la masse. Une fois le programme téléchargé, il faut alors redémarrer l'ESP32 en laissant la pin GPIO0 en l'air. Si on utilise esptool.py pour programmer la carte, ce qui est le cas lorsqu'on dévelope via l'IDE Arduino, on peut automatiser la bascule sur le bootloader en câblant la pin DTR sur GPIO0 et RTS sur RST (EN de l'ESP32), comme indiqué sur cette page. Merci à Oliv' pour l'info.