Il Robot Domotico Personale Pedro, Autonomo e/o RC

da | Lug 14, 2022 | 0 commenti

SCOPO DELLA GUIDA:

  • Realizzare un Robot Domotico Personale Multiruolo che chiameremo per brevità “PEDRO” (PErsonal-Domotic-RObot). Questo robot sarà autonomo e/o radiocomandato, inoltre sarà basato su Arduino Mega 2560 R3 e Espressif ESP8266. PEDRO sarà dotato di ruote Mecanum e collegato tramite Wi-Fi di casa e protocollo MQTT ad Home Assistant, l’Hub domotico open source più diffuso al mondo. Quest’ultimo sarà configurato in modo da poter inviare anche in autonomia eventuali comandi al robot, attraverso l’integrazione degli assistenti vocali Amazon Alexa e Google Home. Infine questa guida ti mostrerà come includere i tuoi comandi personalizzati all’interno di script o automazioni impartibili anche con comandi vocali, e ti illustrerà come fare per visualizzare graficamente i dati telemetrici del robot.

LIVELLO DI DIFFICOLTÀ: medio-alto

  • Nonostante il livello di difficoltà di questo progetto robotico sia medio-alto, lo stesso richiede molteplici abilità manuali e un certo numero di dotazioni strumentali. D’altronde stiamo costruendo un robot autonomo con funzionalità avanzate partendo da zero ovvero dalle sue componenti di base, hardware e software. In altre parole soltanto in parte le acquisteremo dal nostro shop o altrove, per il resto dovremo realizzarle noi con la necessaria strumentazione.

La realizzazione del robot domotico richiede:

  • Abilità di base nel taglio, foratura e incollaggio a freddo di alcune lastre di multistrato di legno,
  • Esperienza nel taglio, piegatura a caldo e foratura di alcune lastre di plexiglass,
  • Saper utilizzare un saldatore, occorrerà per saldare i cavi di alimentazione ai connettori XT60 e agli interruttori,
  • Opzionalmente alcuni elementi possono essere stampati con una stampante 3D, come ad esempio le componenti delle ruote omnidirezionali Mecanum o il minibox contenitore del modulo nRF24L01+.

Come sempre in caso di interazione con componenti elettroniche è caldamente consigliato visionare più volte gli schemi tecnici forniti con il progetto. Questo per comprendere a fondo come effettuare le connessioni tra i vari elementi PRIMA di collegare i dispositivi alla sorgente di alimentazione.

Inoltre è richiesta la conoscenza di base di:

  • Arduino, il microcontrollore più diffuso al mondo, e del suo IDE o ambiente di sviluppo,
  • Raspberry Pi4/Pi3B+, un computer a scheda singola sviluppato nel Regno Unito dalla Raspberry Pi Foundation,
  • Definizione di un “Hub domotico” come Home Assistant (Core 2022.5.5) utilizzato in questo progetto,
  • Impostazioni avanzate del firmware del proprio router Wi-Fi.
  • Che cos’è una batteria ai Polimeri di Litio (LiPo), come si maneggia, come si ricarica e quali precauzioni adottare nell’uso.

CONCETTI AFFRONTATI:

  • Che cos’è e come funziona il protocollo MQTT tra i protocolli più diffusi nei sistemi domotici e/o robotici come in questo caso.
  • Nozioni di base sull’ambiente di sviluppo di Arduino (IDE Arduino) nonchè su uno dei suoi kernel alternativi più diffusi, ovvero FreeRTOS,
  • Installazione e configurazione hardware e software del microcontrollore Wemos Mega 2560 R3 e del chip Wifi Espressif ESP8266 integrato,
  • Preconfigurazione ed installazione dei 4 driver TB6600 per motori Passo Passo (driver stepper motor),
  • Approntare un Hub domotico come Home Assistant su scheda SD e Raspberry Pi4/Pi3B+,
  • Attivazione e configurazione dei Componenti aggiuntivi di Home Assistant, ovvero: Duck DNS, File editor, Grafana, Home Assistant Google Drive Backup, InfluxDB, Log Viewer, Mosquitto broker, Samba share, SSH & Web Terminal, HACS, Alexa Media Player.
  • Caricare e bilanciare le celle di una batteria ai Polimeri di Litio, metodi e procedure.

MATERIALI GREZZI E STRUMENTI DI LAVORO UTILIZZATI:

  • Plexiglass 600x600x4mm (2 lastre),
  • Multistrato in legno 500x500x8mm (2 lastre),
  • Alluminio 50x50x200x2mm (2 profilati a L),
  • Crimpatrice per terminali elettrici,
  • Forbici o pinza spelafili,
  • Tronchesina,
  • Rivettatrice per rivetti filettati, con rivetti M3, M4, M5, M6, M8, M10, M12, per spessori 2-3 mm,
  • Seghetto da traforo per tagliare i pannelli in multistrato di legno,
  • Cutter o Utensile rotativo elettrico per tagliare il plexiglass,
  • Utensile per piegare a caldo il plexiglass (istruzioni per realizzarlo qui),
  • Trapano-avvitatore elettrico, consigliato trapano a colonna per alcune lavorazioni,
  • Stampante 3D e 1 rotolo da 1kg di PETG se intendi realizzare da te alcune componenti (opzionale).

COMPONENTI HARDWARE UTILIZZATE:

  • Wemos Mega 2560 R3 con ESP8266 integrato, corredato da Keyestudio Sensor Shield V1 for Arduino Mega,
  • Modulo integrato Bluetooth HC-05 con convertitore seriale,
  • Modulo nRF24L01+ con convertitore seriale, antenna WiFi 2,4GHz Long Range e modulo di potenza addizionale,
  • Antenna WiFi 2,4GHz 3dBi RP-SMA12cm U.FL IPX IPEX a RP-SMA per ESP8266,
  • IRF520 Modulo Driver MOSFET Uscita PWM 0-24 V 5A per Arduino,
  • Motor Drive Package TB6600 (4 Stepper Driver),
  • Nema17 motore passo-passo 17HS8401 0.55N.m (4 Motori),
  • Ruote tipo Mecanum Wheels da 80mm di diametro autoprodotte (qui istruzioni e files 3D stampabili) o acquistate a parte nel nostro Shop (4 Ruote),
  • Batterie 5000mAh 3S 11.1V 30-45C ai Polimeri di Litio (2 Lipo Battery),
  • UBEC 8A MAX 15A,
  • Connettore XT-60 Maschio,
  • Terminali elettrici da crimpare ai cavi per una connessione stabile e sicura alle morsettiere degli stepper driver,
  • Interruttore switch ON-OFF,
  • Portafusibile e fusibile per automotive da 15A,
  • 1m x Cavi 14 AWG Rosso e Nero e 1m x Cavi 18 AWG Giallo e Nero per le connessioni di alimentazione,
  • 4X20 Cavi Dupont F/F e F/M,
  • 1 LED RGB a 4 poli con Anodo Comune,
  • Set di viti a brugola, rondelle e dadi di varie dimensioni: M2, M3, M4, M5, M6, M8, M12,

COMPONENTI SOFTWARE UTILIZZATE:

  • Sistema operativo Windows 11 o analoghe distribuzioni,
  • IDE Arduino 1.8.16 con le relative librerie necessarie al progetto: Arduino FreeRTOS, ArduinoJson 5.13, Arduino WiFi Link Library (Fork Jandrassy), PubSubClient, OneWire, AccelStepper, SPI, RF24, Adafruit PWM Servo Driver Library, 
  • Home Assitant,
  • I componenti Home Assistant “Alexa Media Player“ e “Notification“, opzionali,

PREREQUISITI:

  • Un PC Workstation o notebook con Windows 10/11 installato e funzionante,
  • Una rete Wi-Fi con Router accessibile via connessione LAN o Wi-Fi,
  • Uno smartphone di ultima generazione con sistema Android, Bluetooth e Wi-Fi per controllo robot e telemetria (opzionale),
  • Infine un saldatore o stazione saldante 2in1 con pistola ad aria calda per guaine termorestringenti,

DISPOSITIVI FISICI UTILIZZATI:

  • PC con Sistema Operativo Windows 10/11 per la programmazione e la compilazione dei Firmware Arduino Mega 2560, per l’installazione e la configurazione dell’Hub Domotico Home Assistant,
  • Raspberry Pi4/Pi3B+ con MicroSD da 32/64 Gb e relativo adattatore USB, sul quale girerà il sistema operativo di Home Assistant corredato di tutti i componenti software aggiuntivi,

ACCESSORI ED ESPANSIONI:

  • Amazon Echo (qualsiasi modello o qualsiasi modello di smart speaker che monti Amazon Alexa come assistente integrato), (opzionale),
  • Radiocomando Fanbotica LongCom X1 basato su Arduino Nano e modulo ricetrasmettitore nRF24L01+ PA LNA RF con Antenna 2.4 GHz 1100m e Regolator adattatore 3.3V, qui il tutorial per auto-costruirtelo o il link per ordinarne il kit disponibile anche pre-assemblato, (opzionale),
  • Braccio Robotico con 6 gradi di libertà, stampato in 3D,
  • Torretta LIDAR,
  • SLAM System,
  • Pan-Tilt con cannoncino laser e dissuasore,

GUIDA DEDICATA A SISTEMI:

Windows_11_logo

NOTE E DISCLAIMER

  • Qualsiasi modifica attuata in proprio è a propria responsabilità personale nonché a proprio rischio e pericolo (i contenuti della presenta pagina hanno puro scopo didattico);
  • Inoltre ogni tipo di modifica attuata in proprio a un dispositivo ne fa decadere garanzia, omologazioni e certificazioni di qualità.

Revisione guida: 1.0

Abstract

Definizione di Domotica

La domotica, derivante dall’unione del termine domus, che in latino significa “casa”, e del suffisso greco ticos, che indica le discipline di applicazione, è la scienza interdisciplinare che si occupa dello studio delle tecnologie adatte a migliorare la qualità della vita nella casa e più in generale negli ambienti abitati dall’uomo.

Nell’applicazione tecnica e fisica di questa disciplina ci si riferisce a tutto quel sistema che mediante uno o più software serva a gestire e controllare (inviando comandi e ricevendo risposte telemetriche) tutti quegli “oggetti domotici” anche detti “entità” ad esso collegati in rete e a loro volta resi responsivi ai comandi stessi perchè dotati di attuatori, sensori e firmware di bordo.

Esempi comuni sono le tapparelle di casa, la saracinesca del garage, il termostato elettronico dello scaldacqua, le luci dei vari ambienti, la tv, lo stereo, etc..

Definizione di Robotica

La robotica è la disciplina dell’ingegneria che studia e sviluppa metodi che permettano a un robot di eseguire dei compiti specifici riproducendo in modo automatico il lavoro umano.

Ci siamo chiesti se fosse possibile realizzare un robot domotico in casa!

Ci siamo più volte chiesti se allo stato di sviluppo attuale della tecnologia delle due discipline, ovvero con la diffusione di software sempre più stabili e condivisi sia per la domotica che per la robotica, come ad esempio del celebre Hub Domotico Home Assistant, e dell’ambiente di sviluppo o IDE Arduino, non fosse possibile realizzare un robot domotico, partendo da ciò che è largamente a disposizione dei maker di tutto il mondo, ovvero le piattaforme di prototipazione rapida come lo stesso Arduino e i chip pensati per l’IOT come l’ESP8266 della Espressif Systems, caratterizzati da Wi-Fi integrato a basso costo, supporto completo al protocollo TCP/IP e funzionalità da microcontrollore.

Pertanto se siamo riusciti a realizzare sia il robot domotico che questo tutorial la risposta non può essere che: “Sì, è possibile!”.

Un compendio per realizzare un vero robot domotico

Sicchè questo vero e proprio compendio sulla interazione tra robotica e domotica guiderà il lettore passo dopo passo nella realizzazione di un robot domotico del tutto autonomo, ma che sarà possibile radiocomandare da uno smartphone via Bluetooth, da una radio RC, o da una apposita interfaccia di Home Assistant.

“Ma a cosa dovrebbe servire precisamente un robot integrato nel software che gestisce la domotica delle nostre case?”

Direi che la risposta più giusta dovrebbe essere: “A tutto ciò che una piattaforma robotica semovente potrebbe servire in una casa e nei suoi ambienti circostanti”, ma così avremmo detto tutto e niente, dunque per scendere ancor di più nel dettaglio mi spingo a citare soltanto alcuni esempi di utilizzo più comuni che vanno dall’agente di sorveglianza H24, al rilevatore di calore, luce, gas, polveri, radioattività, dalle mansioni svolte da un cameriere a quelle di receptionist e portavivande, dalla guida e assistenza agli anziani al ruolo di spazzino in giro per la casa o di tagliaerbe, insomma ci siamo capiti gli utilizzi sono limitati soltanto dalla tua fantasia e dalla dotazione hardware e software!

Potrai controllare il tuo robot domotico PEDRO anche dall’altro capo del mondo.

Tra le innumerevoli funzioni in dotazione al tuo robot domotico troverai anche quella che ti permetterà di sapere in tempo reale che cosa sta facendo PEDRO, e cosa più importante nel caso avrai attivato le funzioni di sorveglianza con apposito sistema di webcam sarai in grado di sapere cosa sta succedendo nella tua abitazione anche a distanza, comodamente dal tuo smartphone, attraverso la APP di Home Assistant.

Si parte

  1. Operazioni preliminari
    1. Preparazione dell’ambiente di lavoro
      1. Caratteristiche di sicurezza obbligatorie dell’impianto elettrico
      2. Dotazione di sicurezza individuale
      3. Procurati tutte le componenti e gli strumenti di lavoro necessari
    2. Elenco componenti hardware del robot domotico
    3. Recuperiamo o acquistiamo le lastre di plexiglass, di multistrato e i profilati di alluminio
    4. Stampiamo le guide di taglio in formato A2 Scala 1:1
    5. Installiamo e configuriamo tutto il software necessario
      1. Scarichiamo l’IDE Arduino dal sito ufficiale
      2. Installiamo e/o configuriamo l’ambiente di sviluppo IDE Arduino sul nostro PC
      3. Procediamo con l’installazione delle librerie Arduino necessarie
      4. Esaminiamo le differenze tra la nostra scheda Wemos Mega 2560 e Arduino Mega 2560
      5. Porte di comunicazione della Wemos Mega 2560
      6. Installazione del driver CH340G
      7. Note sulla libreria Arduino WiFi Link Library (Fork Jandrassy)
      8. Installazione della libreria Arduino WiFi Link Library (Fork Jandrassy)
      9. Selezione, configurazione e verifica della scheda ESP8266 generico
      10. Caricamento del firmware ArduinoFirmwareEsp.ino su Esp8266
      11. Ora installiamo e/o configuriamo Home Assistant su Raspberry Pi
      12. Installiamo e configuriamo i Componenti aggiuntivi di Home Assistant
      13. Scarichiamo e installiamo Amazon Alexa sul nostro smartphone e sul PC e configuriamo il nostro/i nostri Amazon Echo (opzionale)
  2. Realizziamo tutte le parti in multistrato dello chassis di Pedro
  3. Realizziamo la scocca di Pedro sagomando e piegando la lastra di Plexiglass
  4. Installiamo tutta la componentistica Hardware nello chassis di Pedro
  5. Realizziamo il cablaggio e controlliamo la correttezza di tutti i collegamenti più volte
  6. Installiamo il firmware FREERTOS Arduino sulla Wemos 2560
  7. Realizziamo il Long Range Controller
  8. Eseguiamo i test di controllo

Operazioni preliminari

Prima di procedere alla vera e propria realizzazione del nostro robot domotico Pedro, occorre che dedichiamo tutto il tempo necessario alla messa in sicurezza della nostra area di lavoro al fine di rendere prossimo allo zero ogni possibile rischio derivante dalle attività che svolgeremo.

Gli strumenti operativi che utilizzeremo dovranno essere di qualità, evitiamo di risparmiare sulla dotazione strumentale, anche perchè ci servirà sicuramente anche per realizzare i progetti futuri.

La sicurezza innanzitutto! Non dotarsi di protezione, lavorare in un’area di lavoro non idonea, avere arnesi che facilmente si rompono o che peggio possono procurare dei danni fisici a noi o ad altri non è mai un buon affare!

Preparazione dell’ambiente di lavoro

Innanzitutto scegliamo l’area dove opereremo facendo in modo che sia ben illuminata, asciutta, areata e sgombra da oggetti che possano intralciare i nostri movimenti, al netto degli strumenti che utilizzeremo per lavorare.

Per esempio trapano a mano o a colonna, troncatrice etc.. dovranno essere disposti sulle superfici in modo da lasciare tutt’intorno sufficienti spazi operazionali e il più possibile in modo razionale rispettando la sequenza delle varie fasi di lavorazione.

Manteniamo l’area di lavoro in ordine e pulita prima, durante e dopo tutti i cicli di lavorazione.

Dunque niente pezzetti o trucioli di legno o metallo sulle superfici durante le procedure di taglio o foratura, i quali potrebbero facilmente essere proiettati contro di noi o altri presenti dalla rotazione o dai flussi d’aria generati dagli stessi attrezzi di lavoro.

Pertanto è caldamente consigliato l’utilizzo di un bidone aspiratutto per solidi e liquidi molto potente, con fusto raccolta in acciaio inossidabile robusto e resistente.

Caratteristiche di sicurezza obbligatorie dell’impianto elettrico

Dal momento che si opererà con strumentazione elettrica è assolutamente necessario che le prese di corrente, gli adattatori, ed eventuali prolunghe siano del tipo appropriato.

Ognuno dei suddetti elementi deve sopportare il carico di corrente necessario a far funzionare gli strumenti, resistere con ridondanza al calore generato nei cavi elettrici dall’attraversamento dello stesso.

Infine è obbligatorio che l’intero circuito adoperato abbia la messa a terra.

Dotazione di sicurezza individuale

Come in ogni progetto dove occorra adoperare strumenti di taglio o rotativi è indispensabile dotarsi di:

  • Occhiali protettivi da lavoro con protezione laterale,
  • Guanti antitaglio da lavoro,
  • Cuffie antirumore da lavoro,
  • Consigliata una salopette da lavoro.

Per le connessioni elettroniche al fine di non danneggiare le parti elettroniche:

  • Bracciale antistatico,
  • Guanti antistatici.

sicurezza_area_di_lavoro

Procuriamoci tutti gli strumenti di lavoro necessarie alla realizzazione del robot domotico

Bene, è giunto il momento di procurarci tutto l’occorrente per realizzare il nostro robot domotico!

Pertanto cominciamo dagli strumenti di lavoro che ci serviranno, se non li avete potete trovarli forniti in kit nel PEDRO Tools Workit o in parti sciolte nel nostro shop, pagando un solo costo di spedizione, o anche acquistarli altrove:

  1. Una crimpatrice per terminali elettrici corredata da un buon numero di terminali,
  2. Pinza spela-fili,
  3. Tronchesina a becco piatto,
  4. Rivettatrice per rivetti filettati, con rivetti M3, M4, M5, M6, M8, M10, M12, per spessori 2-3 mm,
  5. Seghetto da traforo per tagliare i pannelli in multistrato di legno,
  6. Cutter o Utensile rotativo elettrico per tagliare il plexiglass,
  7. Utensile per piegare a caldo il plexiglass da acquistare o autoprodurre (istruzioni per realizzarlo qui),
  8. Trapano-avvitatore elettrico, consigliato trapano a colonna per alcune lavorazioni,
  9. Stampante 3D e 1 rotolo da 1kg di PETG se intendi realizzare da te alcune componenti (opzionale).
Qui l’elenco delle componenti hardware del robot domotico

Per i componenti hardware necessari al progetto vale lo stesso discorso dei tools, li puoi acquistare già raggruppati nei PEDRO Component kit o singolarmente, risparmiando in ambedue i casi sul costo di spedizione, oppure acquistarli altrove:

  • Wemos Mega 2560 R3 con ESP8266 integrato, corredato da Keyestudio Sensor Shield V1 for Arduino Mega,
  • Modulo integrato Bluetooth HC-05 con convertitore seriale,
  • Modulo nRF24L01+ con convertitore seriale, antenna WiFi 2,4GHz Long Range e modulo di potenza addizionale,
  • Antenna WiFi 2,4GHz 3dBi RP-SMA12cm U.FL IPX IPEX a RP-SMA per ESP8266,
  • IRF520 Modulo Driver MOSFET Uscita PWM 0-24 V 5A per Arduino,
  • Motor Drive Package TB6600 (4 Stepper Driver),
  • Nema17 motore passo-passo 17HS8401 0.55N.m (4 Motori),
  • Ruote tipo Mecanum Wheels da 80mm di diametro autoprodotte (qui istruzioni e files 3D stampabili) o acquistate a parte nel nostro Shop (4 Ruote),
  • Batterie 5000mAh 3S 11.1V 30-45C ai Polimeri di Litio (2 Lipo Battery),
  • UBEC 8A MAX 15A,
  • Connettore XT-60 Maschio,
  • Terminali elettrici da crimpare ai cavi per una connessione stabile e sicura alle morsettiere degli stepper driver,
  • Interruttore switch ON-OFF,
  • Portafusibile e fusibile per automotive da 15A,
  • 1m x Cavi 14 AWG Rosso e Nero e 1m x Cavi 18 AWG Giallo e Nero per le connessioni di alimentazione,
  • 4X20 Cavi Dupont F/F e F/M,
  • 1 LED RGB a 4 poli con Anodo Comune,
  • Set di viti a brugola, rondelle e dadi di varie dimensioni: M2, M3, M4, M5, M6, M8, M12,
Recuperiamo o acquistiamo le lastre di plexiglass, di multistrato e i profilati di alluminio

Procuriamoci dal nostro negozio di bricolage preferito 2 lastre di Plexiglass delle dimensioni di 600x600x4mm, ci occorreranno più avanti per realizzare la scocca del nostro robot, ed il coperchio del Long Range Controller.
2 lastre di multistrato in legno da 500x500x8mm con le quali realizzeremo le basi, ed infine 2 Profilati di Alluminio ad L delle dimensioni: 50x50x200x2mm, che utilizzeremo per fissare joystick e top box del controller.

Stampiamo le guide di taglio in formato A2 Scala 1:1

Effettuiamo il download dei files in PDF recanti i disegni di PEDRO con le linee di taglio e i crocini per realizzare i fori di ancoraggio delle schede elettroniche, rechiamoci in un centro stampa per realizzare le stampe dei files in formato A2 e scala 1:1, utilizzando gli schemi il taglio e la foratura degli elementi in multistrato saranno molto più precisi e veloci.

Preferibilmente facciamo stampare i due schemi di taglio su carta adesiva rimovibile, sarà molto più semplice mantenere in posizione gli schemi durante il taglio e la foratura.

Bottom Cutting Scheme

Side Cutting Scheme

Installiamo e configuriamo tutto il software necessario

A seguire procediamo con l’installazione e la configurazione sul nostro PC dell’ambiente di sviluppo software (IDE Arduino), dei driver, delle librerie, dei firmware, dell’hub domotico personale Home Assistant e dei suoi componenti aggiuntivi, e per finire della APP Amazon Alexa.

Scarichiamo l’IDE Arduino dal sito ufficiale

Otteniamo l’ultima versione dalla pagina di download ufficiale. Possiamo scegliere tra i pacchetti Installer (.exe) e Zip. Scaricheremo il primo che installa direttamente tutto il necessario per utilizzare il software Arduino (IDE), inclusi i driver. Con il pacchetto Zip è necessario installare i driver manualmente. Il file Zip è utile anche se si desidera creare un’installazione portatile .

Al termine del download, procediamo con l’installazione e acconsentiamo al processo di installazione del driver quando viene visualizzato un avviso dal sistema operativo.

IDE_Arduino_Installation

Scegliamo i componenti da installare

IDE_Arduino_Installation

Scegliamo la directory di installazione.

Ide_Arduino_installation

Installazione in corso.

Il processo estrarrà e installerà tutti i file necessari per eseguire correttamente il software Arduino (IDE).

Installazione delle librerie necessarie al progetto robot domotico

Per installare le librerie selezioniamo dalla barra del Menu > Sketch > #include libreria > Gestione Librerie.
Nel campo di ricerca della finestra “Gestore librerie” scriviamo “FreeRTOS”, facciamo clic sul pulsante “Installa”,
attendiamo che la routine del Gestore Librerie completi il processo di installazione, poi ripetiamo gli stessi passi per installare le altre librerie, ovviamente inserendo i seguenti nomi di libreria nel campo di ricerca:

  • ArduinoJson, > ATTENZIONE: INSTALLARE LA VERSIONE 5.13 E NESSUN’ALTRA!
  • PubSubClient,
  • OneWire,
  • AccelStepper,
  • RF24,
  • Adafruit PWM Servo Driver Library,
Esaminiamo le differenze tra la nostra scheda Wemos Mega 2560 e Arduino Mega 2560
arduino_mega_vs_wemos_mega

arduino_mega_vs_wemos_mega

La Wemos Mega 2560 è un clone della scheda Arduino Mega 2560 R3 combinata con un controller Espressif ESp8266.
Quindi, la scheda le stesse dimensioni del controller originale Arduino Mega.

Il vero e proprio chip microcontrollore è un ATmega2560 come nella Arduino Mega, con 54 pin digitali e 16 analogici, 4 porte seriali UART, un cristallo oscillatore a 16 MHz, una porta USB e un jack di alimentazione, un header ICSP e un pulsante di reset.

Ha tre tipi di memoria: Flash, SRAM ed EPROM. La scheda lavora ad una tensione nominale di 5V e sopporta una corrente massima di 40 mA.
Il controller ATmega2560 viene spostato sul lato destro e il controller ESP8266 si trova sul lato sinistro.

Il connettore USB-A qui viene sostituito con un convenzionale tipo-B con Micro-B, e l’interazione del terminale con i componenti può essere eseguita tramite il convertitore CH340G (connesso RX0/TX0 di ATmega2560) a USB-TTL e l’interruttore DIP 8 contatti.

Le caratteristiche della Wemos Mega

Microcontroller ATmega2560
Operating Voltage 5V
Tensione di ingresso (raccomandato) 7-16V
Corrente in uscita a 5V 1,6A
Corrente in uscita a 3.3V 1A
Digital I/O Pins 54 (of which 15 provide PWM output)
Analog Input Pins 16
DC Current per I/O Pin 20 mA
DC Current for 3.3V Pin 50 mA
Flash Memory 256 KB of which 8 KB used by bootloader
SRAM 8 KB
EEPROM 4 KB
Clock Speed 16 MHz
LED_BUILTIN 13
Length 101.52 mm
Width 53.3 mm
Weight 37 g

Il microcontrollore ATmega2560

Il microcontrollore presente sulla scheda WeMos Mega è un ATmega2560 è un AVR RISC 8 bit a bassa potenza prodotto da Atmel ora confluita nella Microchip e unisce 256KB di memoria ISP flash, 8 KB SRAM, 4KB EEPROM, 86 linee I/O general purpose, 32 registri di lavoro general-purpose, un contatore in tempo reale, sei timer , PWM, quattro porte USART, interfaccia seriale a 2 fili, 16 canali A/D a 10-bit, un’interfaccia JTAG per il debugging on-chip.
Il dispositivo raggiunge un throughput di 16 MIPS a 16 MHz e opera tra 4,5-5,5 volt.
Con l’esecuzione di istruzioni potenti in un singolo ciclo di clock, il dispositivo raggiunge un throughput di avvicinamento 1 MIPS per MHz, bilanciando il consumo di energia e l’elaborazione veloce.

ATMEGA2560

ATMEGA2560

Program Memory Type Flash
Program Memory (KB) 256
CPU Speed (MIPS) 16
RAM Bytes 8,192
Data EEPROM (bytes) 4096
Digital Communication Peripherals 4-UART, 5-SPI, 1-I2C
Capture/Compare/PWM Peripherals 4 Input Capture, 4 CCP, 16PWM
Timers 2 x 8-bit, 4 x 16-bit
Comparators 1
Temperature Range (C) -40 to 85
Operating Voltage Range (V) 1.8 to 5.5
Pin Count 100

Modulo ESP8266

Sulla scheda WeMos Mega è istallato un chip ESP8266 prodotto dalla Espressif, si tratta di un SoC (system-on-a-chip) Wi-Fi integrato con un MCU a 32bit LX106, il chip è collegato al microcontrollore ATmega2560 tramite RX3/TX3.

esp8266_pinout

esp8266_pinout

Specifiche dell’ESP8266

802.11 b/g/n
Wi-Fi Direct (P2P), soft-AP
Stack TCP/IP integrato
Integra lo switch TR, l’amplificatore RF e l’antenna
Integra un PLL, il regolatore e un circuito per il controllo della potenza
Potenza in uscita +19.5dBm in modo 802.11b
Corrente a riposo <10uA
La CPU a 32 bit può essere utilizzata per gestire contemporaneamente altre applicazioni
SDIO 1.1/2.0, SPI, UART
STBC, 1×1 MIMO, 2×1 MIMO
A-MPDU & A-MSDU aggregation & 0.4ms guard interval
Accensione e trasmissione < 2ms

Sulla scheda WeMos Mega è presente un connettore maschio 7×2 che permette l’accesso diretto ad alcuni pin del chip ESP8266, la funzione è riportata nella parte inferiore del PCB.

Pin Funzione
1 VCC RXD
2 RST GPIOO
3 CH_PD GPIO2
4 TXD GND
5 GPIO5 GPIO16
6 GPIO4 TOUT
7 GPIO12 GND
Porte di comunicazione della Wemos 2560

WeMos Mega è in grado di comunicare con un computer, con un Arduino o anche con un microcontrollore. Per fare questo la WeMos Mega mette a disposizione 4 UART hardware per la comunicazione seriale di tipo TTL (5V).
La scheda utilizza come convertitore USB-seriale il chip CH340G, in questo caso occorre installare i driver in quanto non riconosciuto automaticamente dal sistema operativo.
WeMos Mega inoltre è dotato di un ICSP (In Circuit Serial Programming) che permette di programmare l’ ATmega2560 ignorando la procedura di caricamento del codice (ad esempio già sviluppato in un altro ambiente) tramite bootloader; in tal modo si ha la possibilità di sfruttare più memoria sulla scheda, passando da 8 KB a 256 KB.
Altra possibilità data dalla WeMos Mega è il chip ESP8266 che permette il collegamento Wi-Fi il chip è collegato al microcontrollore ATmega2560 tramite RX3/TX3.
La scelta del tipo di interfaccia utilizzare può essere fatta agendo su un gruppo di dip switch presenti sulla scheda
Attraverso la libreria SoftwareSerial è possibile effettuare una comunicazione seriale anche sui pin digitali della scheda.

Tabella impostazione dip switch Wemos Mega per scegliere il tipo di connessione

Connessione DIP SWITH 2

1 2

3

4

5

6 7 8 RXD / TXD

USB isolato

OFF OFF

OFF

OFF

OFF

OFF OFF OFF RXD0/TXD0

USB  <->  ATmega2560

OFF OFF

ON

ON

OFF

OFF OFF OFF RXD0/TXD0

USB  <->  ESP8266

(Aggiornamento del firmware o sketch)

OFF OFF

OFF

OFF

ON

ON

ON

OFF RXD0/TXD0

USB <->  ESP8266

(Comunicazione)

OFF OFF

OFF

OFF

ON

ON

OFF OFF RXD0/TXD0

ATmega2560  <->  ESP8266

OFF OFF

OFF

OFF

OFF

OFF OFF OFF RXD0/TXD0

USB  <->  ATmega2560  <->  ESP8266

ON

ON

ON

ON

OFF

OFF OFF OFF RXD3/TXD3

 

Installazione del driver CH340G

La scheda Wemos Mega utilizza come convertitore USB-seriale il chip CH340G invece che il più diffuso chip di FTDI, siccome Windows non supporta nativamente questo chip, il modulo non viene riconosciuto.

Per questo motivo è necessario scaricare il driver dal sito ufficiale del fornitore (sfortunatamente è in cinese).

Una volta eseguito l’unzip del pacchetto, è possibile procedere con l’aggiornamento del driver per la periferica.

Per cui si dovrà lanciare il programma SETUP.EXE.

CH340G_driver_install

CH340G_driver_install

Dopo l’apertura della finestra si effettuerà l’installazione dei driver, che avverrà in automatico premendo INSTALL.
A fine procedura sarà mostra la seguente finestra.

CH340G_driver_install_successfully

CH340G_driver_install_successfully

A questo punto collegando il modulo, questo sarà riconosciuto e Windows configurerà correttamente la nuova porta COM.

CH340G_driver_com_port

CH340G_driver_com_port

Note sulla libreria Arduino WiFi Link Library (Fork Jandrassy)

Prima di installare la libreria “Arduino WiFi Link Library” nella variante riscritta dall’utente Jandrassy, occorre sottolineare alcuni concetti:

La libreria standard “WiFi Link” presente nella raccolta di Arduino non può essere utilizzata in questo progetto in quanto non funzionerebbe con la nostra scheda Wemos Mega 2560 R3 WiFi Esp8266.

La versione Arduino WiFi Link Library (Fork di Jandrassy) permette di utilizzare la porta Seriale 3 della Wemos Mega 2560 con WiFi Esp8266, vedremo in seguito come utilizzare questa funzionalità.

Per ora rechiamoci a questo link: https://github.com/esp8266/arduino-esp8266fs-plugin/relases e scarichiamo il plugin che ci servirà per caricare files sul file system dell’ESP8266 integrato sul nostro microcontrollore Wemos Mega 2560,

Nella directory della tua cartella degli sketch Arduino, crea una directory “tools” se non esiste ancora.
(Puoi trovare la posizione della directory dello sketchbook nell’IDE di Arduino in:
File > Impostazioni > Posizione della cartella degli sketch),
Decomprimi lo strumento nella cartella “tools”,
(il percorso sarà simile a <cartella sketch>/tools/ESP8266FS/tool/esp8266fs.jar).
Riavvia Arduino IDE.

Installazione della libreria Arduino WiFi Link Library (Fork Jandrassy)

Scarichiamo la libreria: WiFi Link Fork Jandrassy

Apriamo o estraiamo lo zip scaricato e copiamo la cartella “ArduinoFirmwareEsp” nella cartella degli schizzi.
Avviamo Arduino IDE e apriamo lo sketch ArduinoFirmwareEsp.ino dal percorso:
File > Cartelle degli sketch > ArduinoFirmwareEsp

NOTA: Di conseguenza si aprono file aggiuntivi come schede nell’IDE. 

IDE-WiFiLink-fw

Selezioniamo la scheda “config.h”, portiamoci alla riga 81 e impostiamo il valore di BAUDRATE_COMMUNICATION a 115200,
Impostiamo adesso i Dip-Switch 5,6,7 della scheda Wemos Mega 2560 su ON, e i Dip-Switch 1,2,3,4,8 su OFF, e controlliamo che lo Switch di selezione della porta seriale sia impostato su RXD0/TXD0, in breve la modalità appena selezionata ci consentirà di trasferire il firmware ArduinoFirmwareEsp.ino sul file system del chip Esp8266.

Wemos Mega 2560 R3 + Esp8266 - Dip-Switch

Wemos Mega 2560 R3 – Dip-Switch impostati per trasferire ArduinoFirmwareEsp.ino sul file system del chip Esp8266

Selezione, configurazione e verifica della scheda ESP8266 generico

Nel menu “Strumenti” seleziona le opzioni della scheda e scegli “ESP8266 generico” dalla sezione ESP8266 del menu Schede. Imposta opzioni dipendenti dall’hardware come frequenza cristalli, frequenza flash, modalità flash, dimensioni flash, led, ripristino.
Quindi scegli le opzioni di utilizzo di esp8266:
“CPU Frequency”: consigliata 80 MHz; 160 MHz produce più calore e ha un consumo energetico maggiore
“LwIP Variant”: v2 Higher Bandwidth,
“Debug port”: Disabled,
“Debug level”: Nessuno è l’impostazione di base,
“Flash Size”: per WiFi Link è opportuno “4M (1M SPIFFS)”, almeno 256 kB sono necessari per SPIFFS,
“Erase flash” è nuova nel pacchetto Arduino esp8266 2.4.1. Per preservare SPIFFS e le credenziali WiFi utilizzare l’opzione “Only Sketch”. Se si cambia dal firmware precompilato, se si modifica l’opzione LwIP o dopo un aggiornamento alla nuova versione del pacchetto core Arduino esp8266, utilizzare “All Flash Contents” per cancellare tutti i parametri impostati da Espressif SDK.

Nota: La cancellazione di tutti i parametri dell’SDK può aiutare se si verificano problemi di stabilità della connessione Wi-Fi.

Ora verifichiamo lo schizzo con il pulsante “Verifica”.
La prima compilazione dopo aver cambiato la scheda di default richiederà più tempo del solito.

Caricamento del firmware ArduinoFirmwareEsp.ino su Esp8266

Colleghiamo la Wemos Mega 2560 R3 WiFi Esp8266 alla USB del nostro PC con il cavo USB in dotazione.
Utilizzare il pulsante “Carica” nell’IDE per caricare il Firmware WiFi Link.

Una volta ultimato il caricamento del Firmware WiFi Link, impostiamo i Dip-Switch della Wemos Mega 2560 R3 in questo modo: 3, 4 su ON, e 1, 2, 5, 6, 7, 8 su OFF, questa è la modalità che ci servirà a breve per caricare il Firmware dell’ATMEGA 2560, il software che fungerà da sistema operativo del nostro robot domotico.

Installiamo e/o configuriamo Home Assistant su Raspberry Pi

Home Assistant è il uno tra gli HUB personali ideali per realizzare una propria domotica personale in modo organico e funzionale.

Prima di avviare il Raspberry Pi, è necessario “installare” il sistema operativo sulla microSD, la quale è il corrispettivo dell’Hard Disk in un comune personal computer.

L’opzione più semplice per installare un’immagine su una microSD o su un disco esterno USB è quella di utilizzare un semplice tool ad interfaccia grafica.

Nel nostro caso utilizzeremo Raspberry Pi Imager, un tool per Windows, macOS e Ubuntu realizzato dalla Raspberry Foundation il quale è in grado di scaricare l’immagine da Internet, permettendoci di scegliere tra varie distribuzioni (oppure usare un’immagine ad hoc presente sul proprio computer), e installarla sulla microSD o su di un disco esterno.

La procedura che adotteremo è la seguente:

  • scarichiamo e installiamo il software Raspberry Pi Imager sul computer di supporto;
  • inseririamo la MicroSD (utilizzando un adattatore USB) nel computer di supporto;
  • eseguiamo Raspberry Pi Imager sul computer di supporto;
  • clicchiamo su “Operating Systems“, scegliamo la voce “Other specific purpose OS” > “Home Assistant” > “Rpi x/xxx” (scegliere il proprio modello di Raspberry Pi);
  • cliccando su Choose storage, selezionare la microSD collegata al computer d’appoggio;
  • clicchiamo “Write” per installare la distribuzione;
  • attendiamo il completamento del task (può metterci anche un’ora, in base alla velocità della connessione Internet – necessaria – e alla velocità di scrittura dati verso la microSD).
Installiamo e configuriamo i Componenti aggiuntivi di Home Assistant

Al fine di dotare il nostro Home Assistant di tutte le funzioni necessarie al nostro progetto procediamo ad installare uno alla volta i seguenti componenti aggiuntivi per i quali di seguito suggeriamo i rispettivi link ufficiali con le procedure aggiornate:

  1. Duck DNS,
  2. File editor,
  3. Grafana,
  4. Home Assistant Google Drive Backup,
  5. InfluxDB,
  6. Log Viewer,
  7. Mosquitto broker,
  8. Samba share,
  9. SSH & Web Terminal,
  10. HACS.
Installiamo Amazon Alexa sul nostro smartphone e/o sul PC e configuriamo il nostro/i nostri Amazon Echo (opzionale)

Se non la abbiamo già fatto in precedenza procediamo a scaricare ed installare la App Amazon Alexa dal repository Play Store nel caso di Android o dallo Store di Apple nel caso di un IOS. Seguiamo poi la procedura canonica indicata da Amazon per configurare il nostro smart speaker Amazon Echo. Ovvero:

  1. Clicchiamo su “Impostazioni Dispositivo”,
  2. Poi sul segno “+” in alto a destra,
  3. Ora colleghiamo ad una presa l’alimentatore fornito in dotazione col nostro smart speaker Amazon Echo e colleghiamo l’atra estremità aquest’ultimo,
  4. Clicchiamo su “Aggiungi Dispositivo” Echo, Casa Intelligente e Accessori dal menu che compare in basso,
  5. Infine dopo aver inserito le informazioni richieste attendiamo che la procedura di rilevazione ed installazione del nostro dispositivo sia completata.

Ripeti le operazioni dal punto 1 al punto 5 per ogni smart speaker Amazon Echo in tuo possesso.

Integriamo Amazon Alexa come “Media Player” su Home Assistant

A partire dalla versione 0.88 di Home Assistant è necessario creare una cartella contenente i file del componente personalizzato, la quale sarà collocata, a sua volta, dentro la cartella “custom_components” all’interno della cartella principale di Home Assistant (ovvero quella nella quale giacciono i file di configurazione come configuration.yaml).

Scarichiamo dunque il pacchetto di installazione e provvediamo a decomprimerlo: esso conterrà una cartella chiamata “alexa_media” la quale rappresenta la cartella dedicata al componente; dunque copiamola dentro la cartella custom_components (laddove quest’ultima non esista, provvediamo a crearla).

IN ALTERNATIVA POSSIAMO INSTALLARE ALEXA MEDIA VIA HACS

Dalla versione 1.3.0 di Home Assistant il componente Alexa Media prevede un’alternativa molto più facile per installarlo: quella di utilizzare HACS.
Per farlo è necessario avere installato una tantum il componete HACS e poi:

  • entrare in HACS;
  • cliccare Integrazioni;
  • cliccare sui tre puntini in alto a destra;
  • selezionar Custom repositories;
  • *alla voce ADD CUSTOM REPOSITORY URL aggiungere – selezionando la categoria integration – il path:
https://github.com/custom-components/alexa_media_player
  • infine, tornando alla voce STORE, cercare e trovare “Alexa Media Player”, cliccarvi sopra e poi, nella pagina apertasi, cliccare su INSTALL. Al termine, riavviare Home Assistant.

*questo specifico punto potrebbe non esser più necessario.

Otteniamo il codice applicativo 2FA

Prima di proseguire con l’integrazione è necessario definire un codice applicativo 2FA.

Il “two-factor-authentication – 2FA” (in italiano “Verifica in due passaggi – 2SV“) è una tecnica sempre più in voga che prevede di autenticarsi a un proprio account Internet non solo tramite username/password, ma anche con un secondo passaggio che, il più delle volte, prevede l’invio di un OTP (one-time-password) via SMS (o altro).

Per utilizzare l’integrazione Alexa Media Player è necessario che tale doppia autenticazione presso l’account Amazon sia attiva sul proprio account.

Colleghiamoci dunque a questo indirizzo e provvediamo alla abilitazione; completiamo la procedura fino al raggiungimento della seguente schermata di riepilogo:

riepilogo_procedura_2SV

riepilogo_procedura_2SV

Clicchiamo ora sulla voce “Aggiungi nuovo telefono o un’app di autenticazione“, e poi sul link “Non riesci ad acquisire il codice a barre?” come mostrato nella seguente immagine:

finestra_aggiungi_metodo_bk_2SV

finestra_aggiungi_metodo_bk_2SV

Si aprirà un box contenente il nostro codice applicativo 2FA:

avviso_procedura_2SV

avviso_procedura_2SV

A questo punto segniamoci da parte tale codice (eg. 35T5 LQSY I5IO 3EFQ LGAJ I6YB JWBY JJPR PYT7 XPPW IDAK SQBJ CVXA), servirà a breve. Chiudiamo la finestra.

Una volta installato il componente “Alexa Media Player” e provveduto al riavvio di Home Assistant, siamo dunque pronti a integrare i dispositivi Alexa (associati al nostro account Amazon) alla nostra domotica.

I dati che ci occorreranno per tale integrazione sono l’username e la password del nostro account presso il webstore nazionale Amazon (.it per l’Italia, .fr per la Francia e così via).

Dunque andiamo alla voce di menu Home Assistant “Configurazione” > “Dispositivi e servizi” per selezionare la voce “Alexa Media Player”

integrazione_alexa_media_player

integrazione_alexa_media_player

Nella schermata successiva inseriamo nei campi richiesti l’username, la password e lo store nazionale di riferimento.

ATTENZIONE: questo è un punto cruciale. Va indicato, per l’Italia, “amazon.it“. Sbagliando questo passaggio ci saranno dei malfunzionamenti a seguire!

configurazione_alexa_media_player

configurazione_alexa_media_player

Spiegazione dei campi:

Indirizzo email Il proprio indirizzo email col quale ci si autentica presso Amazon
Password La relativa password d’accesso
Regione del dominio Amazon Impostiamo amazon.it
URL to access Home Assistant Indirizzo del proprio Home Assistant
2FA Code Il campo precedentemente utilizzato per l’autorizzazione in due fasi. Lasciamolo vuoto.
Built-in 2FA App Key Inseriamo il codice precedentemente ottenuto dall’attivazione della verifica in due fasi.
Dispositivi da includere/eslcudere Eventuali dispositivi presenti sul proprio account Amazon, da includere o escludere esplicitamente, divisi da virgola (eg. “Questo dispositivo”,”App Alexa di Marco” eccetera)

Cliccare su “INVIA” per accedere alla conferma dell’auto-generazione dei codici 2FA da parte dell’app:

password_alexa_media_player

password_alexa_media_player

Clicchiamo su “INVIA” per accedere al captcha finale:

captcha_alexa_media_player

captcha_alexa_media_player

Clicchiamo infine su “INVIA” per proseguire l’integrazione.
A questo punto l’integrazione chiederà di verificare l’autorizzazione lato Amazon che verrà inviata, tipicamente via SMS al cellulare associato all’account (o altri canali):

azione_richiesta_alexa_media_player

azione_richiesta_alexa_media_player

Non clicchiamo subito “INVIA“. Prima rechiamoci presso il sito di Amazon (link inviato via SMS o altri canali) e autorizziamo l’accesso di Home Assistant:

avviso_account_alexa_media_player

avviso_account_alexa_media_player

Autorizzato l’accesso, sarà possibile cliccare su “INVIA” sulla finestra rimasta aperta su Home Assistant.

A questo punto, se tutto sarà andato bene Home Assistant elencherà i device Alexa collegati al proprio account e quindi, da questo momento, integrati all’HUB:

success_installation_alexa_media_player

success_installation_alexa_media_player

In qualunque momento è possibile consultare il proprio elenco di dispositivi integrati presso la voce di menu “Configurazione” > “Dispositivi e servizi” > “Alexa Media Player“.

Realizziamo tutte le parti in multistrato dello chassis di Pedro

Incolliamo gli schemi di taglio e foratura sulle lastre di multistrato di legno (dimensioni: 500x500x8mm) facendo attenzione a che non si formino delle bolle d’aria, aiutiamoci con una riga che utilizzeremo come strumento per far aderire l’adesivo man mano che distaccheremo il suo supporto.

Utilizzando un seghetto per traforo o un seghetto alternativo procediamo al taglio lungo i bordi delle sagome rappresentate nel disegno. Eliminiamo le asperità e le imperfezioni del taglio con della carta vetrata a grana fine.

Ed infine pratichiamo i fori necessari per il fissaggio delle schede elettroniche con una punta da legno da 3mm.

LEFT_PEDRO_CUTTING_SCHEME

LEFT/RIGHT_PEDRO_CUTTING_SCHEME

 

BOTTOM_PEDRO_CUTTING_SCHEME

BOTTOM_PEDRO_CUTTING_SCHEME

Realizziamo la scocca di Pedro sagomando e piegando la lastra di Plexiglass

Con l’ausilio di un Dremel con dischetto abrasivo rotante ricaviamo un pezzo di 940mm x 216mm dalla lastra di Plexiglass. la dimensione in lunghezza sarà maggiore di quella necessaria alla realizzazione della cover finita per il motivo che i bordi definitivi saranno tagliati con precisione soltanto alla fine di questa lavorazione. Usiamo questo accorgimento perchè il plexiglass può subire dei restringimenti del materiale in fase di piegatura a caldo. Utilizzando carta vetrata prima a grana doppia e poi a grana fina lavoriamo bene i bordi per eliminare tutte le imperfezioni.

Provvediamo a tracciare le prime 2 linee di piega sull’elemento lavorato ad una distanza di 100mm dal bordo di ambedue i lati corti e altre due linee più internamente ad una distanza di 61,72mm (51,72mm + 5mm + 5mm) dalle precedenti.

Le misure dei 3 segmenti (centrale + due sponde laterali) devono corrispondere esattamente ai segmenti indicati nel disegno sottostante aumentati di 10mm ciascuno (arco di piegatura), i due segmenti terminali saranno di 20mm più lunghi in quanto verranno rifiniti con un ultimo taglio soltanto alla fine della procedura poggiando la cover sullo chassis e segnando le linee di taglio definitive.

PEDRO_TOP_CUTTING_AND_BLENDING

PEDRO_TOP_CUTTING_AND_BLENDING

Dunque posizioniamo sulla nostra piegatrice per plexiglass il pezzo appena ricavato, fissiamolo in modo che la parte da piegare combaci con il centro dell’elemento riscaldante, impostiamo l’angolo di piegatura a 45° mediante l’apposita staffa del goniometro regolabile e accendiamo la piegatrice. Una volta portata alla temperatura di piegatura, lentamente solleviamo il piano di rotazione e una volta raggiunto l’elemento di battuta della staffa del goniometro, lasciamolo in posizione per qualche minuto spegnendo la macchina. Ripetiamo questa procedura eseguendo tutte le pieghe necessarie. Infine rifiliamo il pezzo col Dremel e la carta vetrata dopo aver tagliato via le estremità in eccesso.

Alla fine dovremo avere un risultato simile al seguente:

PEDRO_TOP

PEDRO_TOP

 

Installiamo tutta la componentistica Hardware nello chassis di Pedro

Prima di installare i 4 moduli stepper driver TB6600 procediamo ad impostarli per gestire i parametri dei Microstep, della Corrente di fase e della corrente di picco dei motori stepper.

A seconda del modello di stepper motor installato dovremo provvedere a configurare gli switch presenti su uno dei lati corti di ogni modulo. Le posizioni ON o OFF dei primi 3 switch presenti servono a configurare la definizione minima del passo (step) del motore in Microstep, secondo le seguente tabella:

Subdivision Pulse / circle  S1  S2  S3
 NC  NC  ON  ON  ON
 1  200  ON  ON  OFF
 2/A  400  ON  OFF  ON
 2/B  400  OFF  ON  ON
 4  800  ON  OFF  OFF
 8  1600  OFF  ON  OFF
 16  3200  OFF  OFF  ON
 32  6400  OFF  OFF  OFF

gli ultimi 3 invece a configurare la corrente di fase, Current (A), e contemporaneamente la Corrente di Picco, PK Current, secondo questa:

Average current  Peak current  S4  S5  S6
 0.5  0.7  ON  ON  ON
 1.0  1.2  ON  OFF  ON
 1.5  1.7  ON  ON  OFF
 2.0  2.2  ON  OFF  OFF
 2.5  2.7  OFF  ON  ON
 2.8  2.9  OFF  OFF  ON
 3.0  3.2  OFF  ON  OFF
 3.5  4.0  OFF  OFF  OFF

Nel nostro caso si tratta di stepper motors del tipo 17HS8401 con un valore di corrente massima per fase di 1.7 A, dunque gli ultimi 3 switch andranno configurati come ON, ON, OFF. I primi tre impostati per un valore di suddivisione dei Microstep pari a 8, ovvero OFF, ON, OFF. Naturalmente accordate i valori necessari al vostro tipo di motori, potete trovare il datasheet relativo in rete effettuando una ricerca con il nome del modello.

TB6600_switch

TB6600_switch

Effettuate tutte le impostazioni non ci resta che montare i 4 Stepper Driver all’interno dello chassis di Pedro, utilizzando i fori di ancoraggio, viti a brugola e dadi M3.

PEDRO_STEPPER_DRIVER_INSTALLATION.fw

PEDRO_STEPPER_DRIVER_INSTALLATION

Ora è giunto il momento di installare dei distanziatori esagonali M3 in plastica sotto la scheda Wemos 2560, utilizzando gli appositi fori presenti su quest’ultima e 6 viti a brugola. Successivamente fissiamo la scheda al centro dello chassis di Pedro avvitando ulteriori 6 viti a brugola esagonali dal lato inferiore del pannello stesso facendole passare attraverso i 6 fori predisposti.

PEDRO_WEMOS_2560_INSTALLATION

PEDRO_WEMOS_2560_INSTALLATION

Realizziamo il cablaggio di Pedro e controlliamo la correttezza di tutti i collegamenti più volte

Per effettuare collegamenti stabili e sicuri tra le parti elettroniche interne realizzeremo alcuni cavi forniti di appositi connettori.

Cominciamo a realizzare 8 cavetti maschio/femmina composti ciascuno di 2 fili Dupont (4 con coppie di fili rossi e gialli e 4 con coppie di fili rossi e arancioni), 1 pin maschio ad una estremità di ciascun filo da un lato e un blocco con alloggiamenti per 3 pin femmina dall’altro.

Inseriamo i terminali maschi nelle morsettiere degli Stepper Driver TB6600 e stringiamo le viti dei morsetti per bloccarli al loro interno. Colleghiamo i terminali femmina delle altre estremità alla Sensor Shield seguendo lo schema indicato di seguito.

Terminato il precedente passaggio procediamo ad applicare i terminali elettrici a boccola isolata ai cavi di collegamento tra motori stepper e stepper driver TB6600 e tra batterie Lipo e questi ultimi. Per facilitare il cablaggio distribuiremo in due gruppi cavi con lo stesso colore (giallo o nero) mediante un connettore a due vie di tipo mammut, in modo da ottenere due soli cavi in uscita verso la seconda batteria Lipo.

Infine per collegare il modulo bluetooth, quello nRF24L01+ e quello LED con la Sensor Shield utilizzeremo cavi Dupont femmina/femmina.

PEDRO_WIRING_SCHEMA

PEDRO_WIRING_SCHEMA

Installiamo il firmware FREERTOS Arduino sulla Wemos 2560
Cos’è l’RTOS?

Un RTOS, anche noto come sistema operativo in tempo reale, è un sistema operativo destinato a soddisfare i requisiti dell’applicazione in tempo reale. È in grado di elaborare i dati così come arrivano, in genere senza ritardi nel buffering. RTOS è la combinazione di chiamate di funzioni predefinite.

Introduzione a FreeRTOS

A differenza dei tipici sistemi operativi in ​​tempo reale, FreeRTOS è appositamente progettato per i microcontrollori. Poiché i microcontrollori sono dotati di risorse limitate abbiamo bisogno di un sistema operativo in base alle risorse disponibili dei microcontrollori. È un kernel open source il che significa che può essere scaricato gratuitamente ed essere utilizzato in applicazioni basate su RTOS.

Impostiamo la Wemos per il caricamento del firmware FreeRTOS

Prima di effettuare il caricamento del firmware FreeRTOS sulla Wemos 2560 occorre rimuovere la scheda Sensor Shield V1 precedentemente installata sulla Wemos per accedere più facilmente ai DIP Switch che servono ad impostarne la modalità di comunicazione. Eseguita questa operazione con molta attenzione, cercando di non danneggiare nessun componente, avremo libero accesso ai DIP Switch che imposteremo per la comunicazione USB <-> ATmega2560, quella che ci occorre per trasferire il firmware sulla Wemos 2560 senza sovrascrivere anche la memoria dell’ESP8266.

Per fare ciò imposteremo gli switch da 1 a 8, rispettivamente su: OFF, OFF, ON, ON, OFF, OFF, OFF, OFF.

Dunque effettuiamo il download del firmware di Pedro cliccando sul pulsante mostrato di seguito.

Non ci resta che collegare il cavo USB alla Wemos 2560 R3 e caricare il firmware cliccando su “Carica” sulla barra dell’IDE Arduino e selezionando il file appena scaricato.

</pre>
/*
Robot PEDRO FREERTOS
Bluetooth & Wi-Fi
by Francesco Onorati, www.fanbotica.com
*/
#include <Arduino_FreeRTOS.h>
//#include "Arduino.h"
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <WiFiLink.h>
#include <Wire.h>
#include <math.h>

//#include <SoftwareSerial.h>
#include <AccelStepper.h>
#include <Servo.h>

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#include <Adafruit_PWMServoDriver.h>

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// you can also call it with a different address and I2C interface
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, Wire);

// Depending on your servo make, the pulse width min and max may vary, you
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!

#define POT1MIN 30 // This is the 'minimum' pulse length count (out of 4096)
#define POT1MAX 100 // This is the 'maximum' pulse length count (out of 4096)
#define POT2MIN 0 // This is the 'minimum' pulse length count (out of 4096)
#define POT2MAX 255 // This is the 'maximum' pulse length count (out of 4096)
#define USMIN 600 // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
#define USMAX 2400 // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates

#define redPin 2
#define greenPin 3
#define bluePin 4
#define COMMON_ANODE //uncomment this line if using a Common Anode LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time jasmess was updated
// constants won't change:

const char* ssid="YOUR LAN NAME";
const char* pass="YOUR PASSWORD";
const char* brokerUser = "BROKER USER";
const char* brokerPass = "BROKER PASSWORD";
const char* broker = "XXX.XXX.XXX.XXX"; // YOUR BROKER IP
const char* inTopic ="home/PEDRO/in";
const char* outTopic ="home/PEDRO/out";
const char* stringa;

int status = WL_IDLE_STATUS; // the Wifi radio's status

IPAddress server(XXX, XXX, XXX, XXX); // IP SERVER

//*** PEDRO SENSORS ***
int MecanumGrip = 22; // PEDRO Entrance Door
int MecanumMotor_left = 23; // robot Motor (left)
int MecanumMotor_right = 24; // robot Motor (right)
String robotGrip;
String robotMotor_left;
String robotMotor_right;

// *** MASTER BEDROOM SENSORS ***
int vMBRDoor = 25;
String MBRdoor;

// Callback function header <- aggiunta altrimenti dava errore
void callback(char* topic, byte* payload, unsigned int length);

WiFiClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);

void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
// Serial.print("Received messages: ");
// Serial.println(topic);
//
// for(int i=0; i<length; i++){
// Serial.print((char) payload[i]);
// }
// Serial.println();
// Serial.println(payload[0]);

if (strncmp((const char*)payload, "ON", 2) == 0) {
setColor(255, 255, 255); // white //
client.publish("home/PEDRO/stat/RESULTLAMP", "ON");
}
if (strncmp((const char*)payload, "OFF", 3) == 0) {
setColor(0, 0, 0); // off
client.publish("home/PEDRO/stat/RESULTLAMP", "OFF");
}
}

void reconnect(){
while(!client.connected()){
//Serial.print("\nConnecting to ");
//Serial.println(broker);
if(client.connect("Mecanum", brokerUser, brokerPass)){
//Serial.print("\nConnected to ");
//Serial.println(broker);
client.publish("home/PEDRO/tele/LWT", "Online");
client.publish("home/PEDRO/tele/LWTLAMP", "Online");
client.publish("home/PEDRO/tele/LWTKANG", "Online");
client.publish("home/PEDRO/tele/LWTSSC", "Online");

client.publish("home/PEDRO/stat/RESULT", "ON");
//client.publish("home/PEDRO/stat/RESULTLAMP", "ON");
client.publish("home/PEDRO/stat/RESULTKANG", "ON");
client.publish("home/PEDRO/stat/RESULTSSC", "ON");

client.publish("home/PEDRO/Connection/Connected", "1");

client.subscribe(inTopic);
client.subscribe("home/PEDRO/cmnd/POWER");
client.subscribe("home/PEDRO/cmnd/PIXYLAMP");

client.subscribe("home/PEDRO/tele/LWT");
client.subscribe("home/PEDRO/tele/LWTLAMP");
client.subscribe("home/PEDRO/tele/LWTSSC");
client.subscribe("home/PEDRO/tele/LWTKANG");

client.subscribe("home/PEDRO/tele/esp8266");
client.subscribe("home/PEDRO/tele/mega2560");
client.subscribe("home/PEDRO/tele/pixy2");
client.subscribe("home/PEDRO/tele/ifrsensor01");
client.subscribe("home/PEDRO/tele/ifrsensor02");
client.subscribe("home/PEDRO/tele/grip");
client.subscribe("home/PEDRO/tele/motorL");
client.subscribe("home/PEDRO/tele/motorR");
client.subscribe("home/MBR/tele/door");
client.setCallback(callback);
} else {
//Serial.println("\n Trying to reconnect");
delay(100);
}
}
}

RF24 radio(48, 53); // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte j1PotX;
byte j1PotY;
byte j2PotX;
byte j2PotY;
byte j1Button;
byte j2Button;
byte pot1;
byte pot2;
byte tSwitch1;
byte tSwitch2;
byte button1;
byte button2;
byte button3;
byte button4;
};
Data_Package data; //Create a variable with the above structure

// our servo # counter (from Receiver_code_01 scketch)
uint8_t servo0 = 0;
uint8_t servo1 = 1;
uint8_t servo2 = 2;
uint8_t servo3 = 3;
uint8_t servo4 = 4;
uint8_t servo5 = 5;

Servo servo01;
Servo servo02;
Servo servo03;
Servo servo04;
Servo servo05;
Servo servo06;

//SoftwareSerial Bluetooth(39, 38); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX)

// Define the stepper motors and the pins the will use
AccelStepper LeftBackWheel(1, 42, 43); // (Type:driver, STEP, DIR) - Stepper1
AccelStepper LeftFrontWheel(1, 40, 41); // Stepper2
AccelStepper RightBackWheel(1, 44, 45); // Stepper3
AccelStepper RightFrontWheel(1, 46, 47); // Stepper4

//#define led 14

int wheelSpeed = 1500;

int lbw[50], lfw[50], rbw[50], rfw[50]; // arrays for storing positions/steps

int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos; // current position
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos; // previous position
int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50]; // for storing positions/steps
int speedDelay = 20;
int index = 0;
int dataIn;
int m = 0;

//define task handles
//TaskHandle_t TaskBTRC_Handler;
//TaskHandle_t TaskTelemetry_Handler;

// define two tasks for Blink & Serial
void TaskBTRC( void *pvParameters );
void TaskTelemetry(void* pvParameters);

// the setup function runs once when you press reset or power the board
void setup() {
pinMode(LED_BUILTIN, OUTPUT); //built in led to show activity

pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
setColor(0, 0, 255); // blue

// Set initial seed values for the steppers
LeftFrontWheel.setMaxSpeed(3000);
LeftBackWheel.setMaxSpeed(3000);
RightFrontWheel.setMaxSpeed(3000);
RightBackWheel.setMaxSpeed(3000);
// pinMode(led, OUTPUT);
servo01.attach(5);
servo02.attach(6);
servo03.attach(7);
servo04.attach(8);
servo05.attach(9);
servo06.attach(10);

Serial.begin(115200);

while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("-------------");
Serial.println("\t > Inizializzazione interfaccia Serial 0 Completata");
//INITIALIZE WIRELESS COMMUNICATION BETWEEN ARDUINO <-> ESP OVER SERIAL 1 AND SERIAL 3
//DO NOT EDIT ANYTHING BELOW
#if !defined(ESP_CH_SPI)
Serial3.begin(115200); // speed must match with BAUDRATE_COMMUNICATION setting in firmware config.h
while (!Serial3) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("\t > Inizializzazione interfaccia Serial 3 Completata");
delay(100);

Serial2.begin(115200);
while (!Serial2) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("\t > Inizializzazione interfaccia Serial 2 Completata");
delay(100);

WiFi.init(&Serial3);
#endif
if (WiFi.checkFirmwareVersion("1.1.0")) {
WiFi.resetESP(); // to clear 'sockets' after sketch upload
delay(100); // let firmware initialize
}

//Check if communication with the wifi module has been established
if (WiFi.status() == WL_NO_WIFI_MODULE_COMM) {
Serial.println("\t > Communication with WiFi module not established.");
while (true);// don't continue:
}

// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
Serial.print("\t > Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);

// wait 10 seconds for connection:
delay(100);
}

// you're connected now, so print out the data:
Serial.println("\t > You're connected to the network");
printCurrentNet();
printWifiData();

if (client.connect("Mecanum", "MQTT USER", "MQTT PASSWORD")) {
client.publish("home/PEDRO/tele/LWT", "Online");
client.publish("home/PEDRO/tele/LWTLAMP", "Online");
client.publish("home/PEDRO/tele/LWTKANG", "Online");
client.publish("home/PEDRO/tele/LWTSSC", "Online");

client.publish("home/PEDRO/stat/RESULT", "ON");
//client.publish("home/PEDRO/stat/RESULTLAMP", "ON");
client.publish("home/PEDRO/stat/RESULTKANG", "ON");
client.publish("home/PEDRO/stat/RESULTSSC", "ON");

client.publish("home/PEDRO/Connection/Connected", "1");

client.subscribe(inTopic);
client.subscribe("home/PEDRO/cmnd/POWER");
client.subscribe("home/PEDRO/cmnd/PIXYLAMP");

client.subscribe("home/PEDRO/tele/LWT");
client.subscribe("home/PEDRO/tele/LWTLAMP");
client.subscribe("home/PEDRO/tele/LWTSSC");
client.subscribe("home/PEDRO/tele/LWTKANG");

client.subscribe("home/PEDRO/tele/esp8266");
client.subscribe("home/PEDRO/tele/mega2560");
client.subscribe("home/PEDRO/tele/pixy2");
client.subscribe("home/PEDRO/tele/ifrsensor01");
client.subscribe("home/PEDRO/tele/ifrsensor02");
client.subscribe("home/PEDRO/tele/grip");
client.subscribe("home/PEDRO/tele/motorL");
client.subscribe("home/PEDRO/tele/motorR");
client.subscribe("home/MBR/tele/door");
delay(100);
Serial.println("\t > Publishing Connection Message to Broker");
delay(100);
client.setCallback(callback);
}

radio.begin();
radio.openReadingPipe(0, address);
radio.setAutoAck(false);
radio.setDataRate(RF24_1MBPS);
radio.setPALevel(RF24_PA_LOW);
radio.startListening(); // Set the module as receiver
resetData();

// Serial.println("8 channel Servo test!");
pwm.begin();
/*
* In theory the internal oscillator (clock) is 25MHz but it really isn't
* that precise. You can 'calibrate' this by tweaking this number until
* you get the PWM update frequency you're expecting!
* The int.osc. for the PCA9685 chip is a range between about 23-27MHz and
* is used for calculating things like writeMicroseconds()
* Analog servos run at ~50 Hz updates, It is importaint to use an
* oscilloscope in setting the int.osc frequency for the I2C PCA9685 chip.
* 1) Attach the oscilloscope to one of the PWM signal pins and ground on
* the I2C PCA9685 chip you are setting the value for.
* 2) Adjust setOscillatorFrequency() until the PWM update frequency is the
* expected value (50Hz for most ESCs)
* Setting the value here is specific to each individual I2C PCA9685 chip and
* affects the calculations for the PWM update frequency.
* Failure to correctly set the int.osc value will cause unexpected PWM results
*/
pwm.setOscillatorFrequency(26900000); //27000000 default
pwm.setPWMFreq(SERVO_FREQ); // Analog servos run at ~50 Hz updates

delay(10);

Serial1.begin(115200); // 38400 IS Default baud rate of the Bluetooth module
Serial1.setTimeout(5);
delay(20);
//Serial.begin(38400);
// Move robot arm to initial position
servo1PPos = 90;
servo01.write(servo1PPos);
servo2PPos = 100;
servo02.write(servo2PPos);
servo3PPos = 120;
servo03.write(servo3PPos);
servo4PPos = 95;
servo04.write(servo4PPos);
servo5PPos = 60;
servo05.write(servo5PPos);
servo6PPos = 110;
servo06.write(servo6PPos);

// Now set up two tasks to run independently.
xTaskCreate(
TaskBTRC
, "BTRC" // A name just for humans
, 128 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL //Parameters passed to the task function
, 2 // Priority, with 2 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, NULL );//Task handle

xTaskCreate(
TaskTelemetry
, "Telemetry"
, 128 // Stack size
, NULL //Parameters passed to the task function
, 1 // Priority
, NULL ); //Task handle
}

// You can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. It's not precise!
void setServoPulse(uint8_t n, double pulse) {
double pulselength;

pulselength = 1000000; // 1,000,000 us per second
pulselength /= SERVO_FREQ; // Analog servos run at ~60 Hz updates
Serial.print(pulselength); Serial.println(" us per period");
pulselength /= 4096; // 12 bits of resolution
Serial.print(pulselength); Serial.println(" us per bit");
pulse *= 1000000; // convert input seconds to us
pulse /= pulselength;
Serial.println(pulse);
pwm.setPWM(n, 0, pulse);
}

void loop()
{
// Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskTelemetry(void* pvParameters){
/*
Serial
Send "s" or "r" through the serial port to control the suspend and resume of the LED light task.
This example code is in the public domain.
*/
(void) pvParameters;
for (;;) // A Task shall never return or exit.
{

// Check for incoming data from BT module
if (Serial1.available() > 0) {
dataIn = Serial1.read(); // Read the data from BT module

if (dataIn == 0) {
m = 0;
}
if (dataIn == 1) {
m = 1;
}
if (dataIn == 2) {
m = 2;
}
if (dataIn == 3) {
m = 3;
}
if (dataIn == 4) {
m = 4;
}
if (dataIn == 5) {
m = 5;
}
if (dataIn == 6) {
m = 6;
}
if (dataIn == 7) {
m = 7;
}
if (dataIn == 8) {
m = 8;
}
if (dataIn == 9) {
m = 9;
}
if (dataIn == 10) {
m = 10;
}
if (dataIn == 11) {
m = 11;
}
if (dataIn == 12) {
m = 12;
}
if (dataIn == 14) {
m = 14;
}
if (dataIn == 16) {
m = 16;
}
if (dataIn == 17) {
m = 17;
}
if (dataIn == 18) {
m = 18;
}
if (dataIn == 19) {
m = 19;
}
if (dataIn == 20) {
m = 20;
}
if (dataIn == 21) {
m = 21;
}
if (dataIn == 22) {
m = 22;
}
if (dataIn == 23) {
m = 23;
}
if (dataIn == 24) {
m = 24;
}
if (dataIn == 25) {
m = 25;
}
if (dataIn == 26) {
m = 26;
}
if (dataIn == 27) {
m = 27;
}

// Move the Mecanum wheels platform
if (m == 4) {
moveSwLeft();
}
if (m == 5) {
moveSwRight();
}
if (m == 2) {
moveForward();
}
if (m == 7) {
moveBackward();
}
if (m == 3) {
moveRightForward();
}
if (m == 1) {
moveLeftForward();
}
if (m == 8) {
moveRightBackward();
}
if (m == 6) {
moveLeftBackward();
}
if (m == 9) {
rotateLeft();
}
if (m == 10) {
rotateRight();
}

if (m == 0) {
stopMoving();
}

// Mecanum wheels speed
if (dataIn > 30 & dataIn < 100) {
wheelSpeed = dataIn * 20;
}

// Move robot arm
// Move servo 1 in positive direction
while (m == 16) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo01.write(servo1PPos);
servo1PPos++;
delay(speedDelay);
}
// Move servo 1 in negative direction
while (m == 17) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo01.write(servo1PPos);
servo1PPos--;
delay(speedDelay);
}
// Move servo 2
while (m == 19) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo02.write(servo2PPos);
servo2PPos++;
delay(speedDelay);
}
while (m == 18) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo02.write(servo2PPos);
servo2PPos--;
delay(speedDelay);
}
// Move servo 3
while (m == 20) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo03.write(servo3PPos);
servo3PPos++;
delay(speedDelay);
}
while (m == 21) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo03.write(servo3PPos);
servo3PPos--;
delay(speedDelay);
}
// Move servo 4
while (m == 23) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo04.write(servo4PPos);
servo4PPos++;
delay(speedDelay);
}
while (m == 22) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo04.write(servo4PPos);
servo4PPos--;
delay(speedDelay);
}
// Move servo 5
while (m == 25) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo05.write(servo5PPos);
servo5PPos++;
delay(speedDelay);
}
while (m == 24) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo05.write(servo5PPos);
servo5PPos--;
delay(speedDelay);
}
// Move servo 6
while (m == 26) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo06.write(servo6PPos);
servo6PPos++;
delay(speedDelay);
}
while (m == 27) {
if (Serial1.available() > 0) {
m = Serial1.read();
}
servo06.write(servo6PPos);
servo6PPos--;
delay(speedDelay);
}

// If arm speed slider is changed
if (dataIn > 101 & dataIn < 250) {
speedDelay = dataIn / 10; // Change servo speed (delay time)
}

// If button "SAVE" is pressed
if (m == 12) {
//if it's initial save, set the steppers position to 0
if (index == 0) {
LeftBackWheel.setCurrentPosition(0);
LeftFrontWheel.setCurrentPosition(0);
RightBackWheel.setCurrentPosition(0);
RightFrontWheel.setCurrentPosition(0);
}
lbw[index] = LeftBackWheel.currentPosition(); // save position into the array
lfw[index] = LeftFrontWheel.currentPosition();
rbw[index] = RightBackWheel.currentPosition();
rfw[index] = RightFrontWheel.currentPosition();

servo01SP[index] = servo1PPos; // save position into the array
servo02SP[index] = servo2PPos;
servo03SP[index] = servo3PPos;
servo04SP[index] = servo4PPos;
servo05SP[index] = servo5PPos;
servo06SP[index] = servo6PPos;
index++; // Increase the array index
m = 0;
}

// If button "RUN" is pressed
if (m == 14) {
runSteps();

// If button "RESET" is pressed
if (dataIn != 14) {
stopMoving();
memset(lbw, 0, sizeof(lbw)); // Clear the array data to 0
memset(lfw, 0, sizeof(lfw));
memset(rbw, 0, sizeof(rbw));
memset(rfw, 0, sizeof(rfw));
memset(servo01SP, 0, sizeof(servo01SP)); // Clear the array data to 0
memset(servo02SP, 0, sizeof(servo02SP));
memset(servo03SP, 0, sizeof(servo03SP));
memset(servo04SP, 0, sizeof(servo04SP));
memset(servo05SP, 0, sizeof(servo05SP));
memset(servo06SP, 0, sizeof(servo06SP));
index = 0; // Index to 0
}
}

LeftFrontWheel.runSpeed();
LeftBackWheel.runSpeed();
RightFrontWheel.runSpeed();
RightBackWheel.runSpeed();
}
else {

// Check whether there is data to be received
if (radio.available()) {
radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
lastReceiveTime = millis(); // At this moment we have received the data

// nRF24L01+ RADIO-RC - MAPPING COMANDI RC POSIZIONI SERVO

int posiz1 = data.j1PotX;
// do something different depending on the range value:
if (posiz1 < 100) {
moveSwLeft();
//Serial.println(posiz1);
}
if (posiz1 > 160) {
moveSwRight();
//Serial.println(posiz1);
}
// else {
// stopMoving();
//// Serial.println("0");
// }
int posiz2 = data.j1PotY;
// do something different depending on the range value:
if (posiz2 > 160) {
moveForward();
// Serial.println("2");
}
if (posiz2 < 100) {
moveBackward();
// Serial.println("7");
}

if (posiz1 == 0 && posiz2 == 254) {
moveLeftForward();
// Serial.println("1");
}

if (posiz1 == 254 && posiz2 == 254) {
moveRightForward();
// Serial.println("3");
}

if (posiz1 == 0 && posiz2 == 0) {
moveLeftBackward();
// Serial.println("6");
}

if (posiz1 == 254 && posiz2 == 0) {
moveRightBackward();
// Serial.println("8");
}

if (posiz1 < 160 && posiz1 > 100 && posiz2 < 160 && posiz2 > 100) {
stopMoving();
// Serial.println("0");
}

// else {
// stopMoving();
//// Serial.println("0");
// }
//int posiz3 = data.pot2;
int posiz4 = data.j2PotX;
// do something different depending on the range value:
if (posiz4 > 160) {
rotateRight();
// Serial.println("10");
}
if (posiz4 < 100) {
rotateLeft();
// Serial.println("9");
}
// else {
// stopMoving();
//// Serial.println("0");
// }

int posiz5 = data.j2PotY;
// do something different depending on the range value:
if (posiz5 > 160) {
moveForward();
// Serial.println("2");
}
if (posiz5 < 100) {
moveBackward();
// Serial.println("7");
}
// else {
// stopMoving();
//// Serial.println("0");
// }

int posiz0 = map(data.pot1, 0, 255, POT1MIN, POT1MAX);
// do something different depending on the range value:
if (posiz0 > 30) {
wheelSpeed = posiz0 * 20;
// Serial.println("WheelSpeed * 20");
}


// Print the data in the Serial Monitor
// Serial.print("j1PotX: ");
// Serial.print(data.j1PotX);
// Serial.print("; j1PotY: ");
// Serial.print(data.j1PotY);
// Serial.print(" j2PotX: ");
// Serial.print(data.j2PotX);
// Serial.print("; j2PotY: ");
// Serial.print(data.j2PotY);
//
// Serial.print(" j1Button: ");
// Serial.print(data.j1Button);
// Serial.print("; j2Button: ");
// Serial.print(data.j2Button);
//
// Serial.print(" pot1: ");
// Serial.print(data.pot1);
// Serial.print("; pot2: ");
// Serial.print(data.pot2);
//
// Serial.print("; tSwitch1: ");
// Serial.print(data.tSwitch1);
// Serial.print("; tSwitch2: ");
// Serial.println(data.tSwitch2);
}
// // Check whether we keep receving data, or we have a connection between the two modules
// currentTime = millis();
// if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
// resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone has a throttle up and we lose connection, it can keep flying unless we reset the values
// }

&nbsp;

//int posiz0 = map(data.pot2, 0, 255, J0YMIN, J0YMAX);
//int posiz1 = map(data.j2PotX, 0, 255, J0YMIN, J0YMAX);
//int posiz2 = map(data.j2PotY, 0, 255, J0YMIN, J0YMAX);

//pwm.setPWM(servo0, 0, posiz0);
//pwm.setPWM(servo1, 0, posiz1);
//pwm.setPWM(servo2, 0, posiz2);

LeftFrontWheel.runSpeed();
LeftBackWheel.runSpeed();
RightFrontWheel.runSpeed();
RightBackWheel.runSpeed();
}
// vTaskDelay( 2 / portTICK_PERIOD_MS );
}
}

void TaskBTRC(void *pvParameters) // This is a task.
{
(void) pvParameters;
pinMode(LED_BUILTIN, OUTPUT);
for (;;) // A Task shall never return or exit.
{
// //Serial.println(11);
// digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
// vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
// digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
// vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second

// MQTT ESP8266 put your main code here, to run repeatedly:
if (!client.connected()){
reconnect();
}
stringa = char("ok");
client.publish("home/PEDRO/stat/RESULTKANG", stringa);
client.loop();
//Serial.println("-------------");
//delay(1);
// azione();
//jasmess();
vTaskDelay( 4000 / portTICK_PERIOD_MS );
}
}

void moveForward() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveBackward() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void moveSwRight() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveSwLeft() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void rotateLeft() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void rotateRight() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void moveRightForward() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveRightBackward() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(0);
}
void moveLeftForward() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(0);
}
void moveLeftBackward() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(-wheelSpeed);
}
void stopMoving() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(0);
}

// Automatic mode custom function - run the saved steps
void runSteps() {
while (dataIn != 13) { // Run the steps over and over again until "RESET" button is pressed
for (int i = 0; i <= index - 2; i++) { // Run through all steps(index)
if (Serial1.available() > 0) { // Check for incomding data
dataIn = Serial1.read();
if ( dataIn == 15) { // If button "PAUSE" is pressed
while (dataIn != 14) { // Wait until "RUN" is pressed again
if (Serial1.available() > 0) {
dataIn = Serial1.read();
if ( dataIn == 13) {
break;
}
}
}
}
// If speed slider is changed
if (dataIn > 100 & dataIn < 150) {
speedDelay = dataIn / 10; // Change servo speed (delay time)
}
// Mecanum wheels speed
if (dataIn > 30 & dataIn < 100) {
wheelSpeed = dataIn * 10;
dataIn = 14;
}
}
LeftFrontWheel.moveTo(lfw[i]);
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.moveTo(lbw[i]);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.moveTo(rfw[i]);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.moveTo(rbw[i]);
RightBackWheel.setSpeed(wheelSpeed);

while (LeftBackWheel.currentPosition() != lbw[i] & LeftFrontWheel.currentPosition() != lfw[i] & RightFrontWheel.currentPosition() != rfw[i] & RightBackWheel.currentPosition() != rbw[i]) {
LeftFrontWheel.runSpeedToPosition();
LeftBackWheel.runSpeedToPosition();
RightFrontWheel.runSpeedToPosition();
RightBackWheel.runSpeedToPosition();
}
// Servo 1
if (servo01SP[i] == servo01SP[i + 1]) {
}
if (servo01SP[i] > servo01SP[i + 1]) {
for ( int j = servo01SP[i]; j >= servo01SP[i + 1]; j--) {
servo01.write(j);
delay(speedDelay);
}
}
if (servo01SP[i] < servo01SP[i + 1]) {
for ( int j = servo01SP[i]; j <= servo01SP[i + 1]; j++) {
servo01.write(j);
delay(speedDelay);
}
}

// Servo 2
if (servo02SP[i] == servo02SP[i + 1]) {
}
if (servo02SP[i] > servo02SP[i + 1]) {
for ( int j = servo02SP[i]; j >= servo02SP[i + 1]; j--) {
servo02.write(j);
delay(speedDelay);
}
}
if (servo02SP[i] < servo02SP[i + 1]) {
for ( int j = servo02SP[i]; j <= servo02SP[i + 1]; j++) {
servo02.write(j);
delay(speedDelay);
}
}

// Servo 3
if (servo03SP[i] == servo03SP[i + 1]) {
}
if (servo03SP[i] > servo03SP[i + 1]) {
for ( int j = servo03SP[i]; j >= servo03SP[i + 1]; j--) {
servo03.write(j);
delay(speedDelay);
}
}
if (servo03SP[i] < servo03SP[i + 1]) {
for ( int j = servo03SP[i]; j <= servo03SP[i + 1]; j++) {
servo03.write(j);
delay(speedDelay);
}
}

// Servo 4
if (servo04SP[i] == servo04SP[i + 1]) {
}
if (servo04SP[i] > servo04SP[i + 1]) {
for ( int j = servo04SP[i]; j >= servo04SP[i + 1]; j--) {
servo04.write(j);
delay(speedDelay);
}
}
if (servo04SP[i] < servo04SP[i + 1]) {
for ( int j = servo04SP[i]; j <= servo04SP[i + 1]; j++) {
servo04.write(j);
delay(speedDelay);
}
}

// Servo 5
if (servo05SP[i] == servo05SP[i + 1]) {
}
if (servo05SP[i] > servo05SP[i + 1]) {
for ( int j = servo05SP[i]; j >= servo05SP[i + 1]; j--) {
servo05.write(j);
delay(speedDelay);
}
}
if (servo05SP[i] < servo05SP[i + 1]) {
for ( int j = servo05SP[i]; j <= servo05SP[i + 1]; j++) {
servo05.write(j);
delay(speedDelay);
}
}

// Servo 6
if (servo06SP[i] == servo06SP[i + 1]) {
}
if (servo06SP[i] > servo06SP[i + 1]) {
for ( int j = servo06SP[i]; j >= servo06SP[i + 1]; j--) {
servo06.write(j);
delay(speedDelay);
}
}
if (servo06SP[i] < servo06SP[i + 1]) {
for ( int j = servo06SP[i]; j <= servo06SP[i + 1]; j++) {
servo06.write(j);
delay(speedDelay);
}
}
}
}
}

void resetData() {
// Reset the values when there is no radio connection - Set initial default values
data.j1PotX = 125;
data.j1PotY = 119;
data.j2PotX = 127;
data.j2PotY = 129;
data.j1Button = 1;
data.j2Button = 1;
data.pot1 = 1;
data.pot2 = 1;
data.tSwitch1 = 1;
data.tSwitch2 = 1;
data.button1 = 1;
data.button2 = 1;
data.button3 = 1;
data.button4 = 1;
}

void printWifiData() {
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
Serial.println(ip);

// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
Serial.print(mac[5], HEX);
Serial.print(":");
Serial.print(mac[4], HEX);
Serial.print(":");
Serial.print(mac[3], HEX);
Serial.print(":");
Serial.print(mac[2], HEX);
Serial.print(":");
Serial.print(mac[1], HEX);
Serial.print(":");
Serial.println(mac[0], HEX);

}

void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());

// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
Serial.print(bssid[5], HEX);
Serial.print(":");
Serial.print(bssid[4], HEX);
Serial.print(":");
Serial.print(bssid[3], HEX);
Serial.print(":");
Serial.print(bssid[2], HEX);
Serial.print(":");
Serial.print(bssid[1], HEX);
Serial.print(":");
Serial.println(bssid[0], HEX);

// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);

// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}

void jasmess() {
//long K1PI = (K1.getPI().value()) * 379 / 1000; // metri
//long K1Min = K1.getMin().value();
//long K1Max = K1.getMax().value();
//long K1Speed = (K1.gets().value()) * 379 / 1000; // metri al secondo
//long K2PI = (K2.getPI().value()) * 379 / 1000; // metri
//long K2Min = K2.getMin().value();
//long K2Max = K2.getMax().value();
//long K2Speed = (K2.gets().value()) * 379 / 1000; // metri al secondo

StaticJsonBuffer<300> JSONbuffer; //se usato deve essere inferiore allo stack size della task
JsonObject& JSONencoder = JSONbuffer.createObject();

//JSONencoder["K1PI"] = K1PI;
//JSONencoder["K1Min"] = K1Min;
//JSONencoder["K1Max"] = K1Max;
//JSONencoder["K1Speed"] = K1Speed;
//JSONencoder["K2PI"] = K2PI;
//JSONencoder["K2Min"] = K2Min;
//JSONencoder["K2Max"] = K2Max;
//JSONencoder["K2Speed"] = K2Speed;
// JsonArray& values = JSONencoder.createNestedArray("values");
//
// values.add(20);

char JSONmessageBuffer[100];
JSONencoder.printTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));
//Serial.println("Sending message to MQTT topic..");
//Serial.println(JSONmessageBuffer);

if (client.publish("home/PEDRO/stat/RESULTKANG", JSONmessageBuffer) == true) {
//Serial.println("Success sending message");
} else {
//Serial.println("Error sending message");
}
// delay(1);
}

//BLINK BUILT IN LED TO SHOW SENSOR ACTIVITY
void blink() {
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
}

void afferra()
{
/* // Example - Follow set of positions
for(int i=0; i<numPos; i++)
{
// Set positions from array
tmpx = posListXYZWa[i][0];
tmpy = posListXYZWa[i][1];
tmpz = posListXYZWa[i][2];
tmpwa = posListXYZWa[i][3];
tmpg = posListGWr[i][0];
tmpwr = posListGWr[i][1];

// Display "current" position
//Serial.print("tmpx = "); Serial.print(tmpx, DEC); Serial.print("\ttmpy = "); Serial.print(tmpy, DEC); Serial.print("\ttmpz = "); Serial.print(tmpz, DEC); Serial.print("\ttmpg = "); Serial.print(tmpg, DEC); Serial.print("\ttmpwa = "); Serial.print(tmpwa, DEC); Serial.print("\ttmpwr = "); Serial.println(tmpwr, DEC);
//Serial.print("Delay = "); Serial.println(posListDelay[i], DEC); Serial.println("");

// Move arm
Arm(tmpx, tmpy, tmpz, tmpwa, tmpg, tmpwr);

// Pause for the required delay
lastReferenceTime = millis();
while(millis() <= (posListDelay[i] + lastReferenceTime)){};
}
*/
// 1. robot Grip
if (digitalRead(MecanumGrip) == LOW && robotGrip == "open") {
client.publish("home/PEDRO/stat/grip", "CLOSED");
robotGrip = "closed";
blink();
} else if (digitalRead(MecanumGrip) == HIGH && robotGrip == "closed") {
client.publish("home/PEDRO/stat/grip", "OPEN");
robotGrip = "open";
blink();
}
}

void setColor(int red, int green, int blue)
{
#ifdef COMMON_ANODE
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
#endif
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
<pre>
Realizziamo il Long Range Controller

 

Long-Range_Controller

Long-Range_Controller

Eseguiamo i test di controllo

0 commenti

Invia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.

Pin It on Pinterest

Share This