Remerciement à Jpbricole

Bonjour
Il y a quelques mois, j'avais ouvert un topic afin de faire une demande pour pouvoir transférer un courant venant d'une prise jack 3.5 vers du Bluetooth.

Lors de ma demande de projet, j'ai eu la joie de faire la connaissance de Jean-Pierre, qui m'a gentiment proposé de m'aider à mener mon projet.

Après ces quelques mois d'absence dû à des problèmes médicaux, nous avons repris le projet et ce qu'il m'a fait est bleffant !!

Pour les infos techniques, je laisse Jean-Pierre expliquer le matériel utilisé.
Concernant le rendu, voilà ce que ça donne

La prochaine étape est de pouvoir commander ses huit fonctions avec une commande vocale. OK Google. Nous allons essayer en partant sur ce projet

Bonjour!

Pour le matériel, que du classique:


dans cette version, il n'y a pas la LED de signalisation.
La prochaine étape, à part l'adaptation à OK Google, sera la miniaturisation au moyen de switches électroniques.

Le programme:

/*
Name:       AF_foufouner_Fauteuil32joystick.ino
Created:	08.01.2025 11:39:05
Author:     jpbbricole
			https://forum.arduino.cc/t/jack-3-5-vers-bluetooth/1292064
Remarque:
*/

#include <Adafruit_NeoPixel.h> // Gestion des LED RGB Neopixel     https://github.com/adafruit/Adafruit_NeoPixel
#include <BluetoothSerial.h>
BluetoothSerial btSerial;

//------------------------------------- Relais (rel)
const int cmdRelaisPin[] = {13, 12, 14, 27, 26, 25, 33, 32}; // Montage jpbbricole
const int cmdRelaisNombre = sizeof(cmdRelaisPin) / sizeof(cmdRelaisPin[0]);     // Nombre de relais
int cmdRelaisEtatOn = LOW; // Etat pour faire tirer les relais

//------------------------------------- Joystick (joy)
const int joyValMax = 4095; // Valeur maximum (UNO 1023  ESP32 4095)
enum {joyPosBas, joyPosMilieu, joyPosHaut}; // Liste des positions

//------------------------------------- Bluetooth (bt)
String btStatusLabel[] = {"On line", "Off line"};
enum {btStatusOffLine, btStatusOnLine};  // Liste des états du BT
int btStatus = btStatusOffLine;  // BT déconnecté

unsigned long btWatchdogTempo = 1000;  // Temps de surveillance BT
unsigned long btWatchdogMillis = millis();  // Temps de surveillance BT, chrono
const int btLedActivityPin = 2; //2;  // Temoin d'activité du BT
const int btLedActivityEtatOn = HIGH;  // Temoin d'activité du BT etat allumée
const String btNom = "NomDuBluetooth"; // Nom Bluetooth

//------------------------------------- LED signalisation (signLed)
enum signLedIndex {signLedFctInfo, signLedFctNombre};

const int signLedBusPin = 5; // Bus des LED Neopixel
const int signLebBrightMax = 25;     // LED Luminosité maximum

Adafruit_NeoPixel signLed = Adafruit_NeoPixel(signLedFctNombre, signLedBusPin, NEO_GRB + NEO_KHZ800);     // Création de l'objet Neopixel signLed

enum signLedColorsIndex {signColGreen, signColBlue, signColRed, signColOrange, signColYellow, signColWithe, signColOff, signColLatest};
uint32_t signLedColors[signColLatest];     // Valeurs RGB pour les couleurs (Tableau)
const unsigned long signledBlinkTempo = 250;     // Periode de clignotement
unsigned long signledBlinkMillis = millis();     // Periode de clignotement, chrono

void setup()
{
	Serial.begin(115200);  // Console
	btSerial.begin(btNom); //Bluetooth device name FC:E8:C0:7B:A0:52

	signLedInitialisation();
	//-------------------------------- LED de signalisation
	signLedInitialisation();
	signLedDisplay(signLedFctInfo, signColBlue, 0);

	//delay(500);
	Serial.println("Commande de fauteuil avec " + String(cmdRelaisNombre) + " relais");

	for (int r = 0; r < cmdRelaisNombre; r ++)     // Initialisation des pin des relais
	{
		pinMode(cmdRelaisPin[r], OUTPUT);
		digitalWrite(cmdRelaisPin[r], !cmdRelaisEtatOn);     // Faire tomber le relais
	}

	pinMode(btLedActivityPin, OUTPUT);
	digitalWrite(btLedActivityPin, !btLedActivityEtatOn);
	
	relAllOff();
	btStatus = btStatusOffLine;
	
	sysInfo();
	delay(500);
	signLedDisplay(signLedFctInfo, signColGreen, 0);
}

void loop()
{
	//--------------------------------- Commandes moniteur
	if (Serial.available())
	{
		btStatus = btStatusOnLine;
		signLedDisplay(signLedFctInfo, signColBlue, 0);
		btWatchdogMillis = millis();  // Redémarrage du watchdog du BT
		cmdExecute(Serial.readStringUntil('\n'));     // Réception de la commande terminée par Nouvelle ligne
	}
	
	//--------------------------------- Commandes Bluetooth
	if (btSerial.available())
	{
		btStatus = btStatusOnLine;
		digitalWrite(btLedActivityPin, btLedActivityEtatOn);
		signLedDisplay(signLedFctInfo, signColBlue, 0);

		btWatchdogMillis = millis();  // Redémarrage du watchdog du BT
		cmdExecute(btSerial.readStringUntil('\n'));     // Réception de la commande terminée par Nouvelle ligne
	}
	
	if (btStatus == btStatusOnLine && (millis() - btWatchdogMillis >= btWatchdogTempo))  // Si plus de réception BT
	{
		relAllOff();
		digitalWrite(btLedActivityPin, !btLedActivityEtatOn);
		signLedDisplay(signLedFctInfo, signColGreen, 0);
		btStatus = btStatusOffLine;
	}
}

//------------------------------------- Commandes (cmd)
void cmdExecute(String cmdRx)
{
	cmdRx.trim();  // Nettoyage de la chaine recue
	cmdRx.toUpperCase();  // Tout en majuscules
	Serial.println("Commande : " + cmdRx);

	if (cmdRx.startsWith("RM")) // Pour set relais manuellement
	{
		cmdRx.replace("RM", ""); // Supprimer le début de la commande
		relSetManuel(cmdRx.substring(0, 1));
	}
	else if (cmdRx.startsWith(">>")) // Etat des relais de BT
	{
		cmdRx.replace(">>", ""); // Supprimer le début de la commande pour garder la valeur
		relSet(cmdRx);
	}
	else if (cmdRx.startsWith("BTWD")) // Pour Bluetooth watchdog
	{
		cmdRx.replace("BTWD", ""); // Supprimer le début de la commande pour garder la valeur
		btWatchdogTempo = cmdRx.toInt();
		Serial.println("Watchdog Bluetooth:" + String(btWatchdogTempo));
	}
	else
	{
		Serial.println("Commande inconnue: " + cmdRx);
		signLedWarning(5, 150);     // LED Warning
	}	
}

//------------------------------------- Commande relais (rel)
void relSetManuel(String relMan) // Sous forme RM11 pour faire tirer le premier relais, RM10 pour le faire tomber RM31 pour faire tirer le 3eme ...
{
	int relNum = relMan.substring(0, 1).toInt()  -1; // Numéro du relais -1, tableaux débutent à 0
	//relNum = constrain(relNum, 0, cmdRelaisNombre -1); // Pour délimiter le numéro des relais

	if (relNum < 0 || relNum > (cmdRelaisNombre -1))
	{
		Serial.println("No. de relais Invalide: " + relMan);
		signLedWarning(3, 150);     // LED Warning
		return;
	}
	digitalWrite(cmdRelaisPin[relNum], cmdRelaisEtatOn);     // Faire tirer ou tomber le relais

	relEtatList();
}

void relSet(String relStatus)
{
	static boolean relaisTire;
	
	if (relStatus.indexOf("H") > -1) // Si un relais est tiré
	{
		Serial.println("Etat relais " + relStatus); // Sous forme LLHLLLLL pour faire tirer le 3eme relais, par exemple
		signLedDisplay(signLedFctInfo, signColYellow, 0);
		relaisTire = true;
	}
	else
	{
		if (relaisTire)
		{
			Serial.println("Etat relais " + relStatus);
			relaisTire = false;
		}
	}


	for (int r = 0; r < cmdRelaisNombre; r ++)     // Initialisation des pin des relais
	{
		if (relStatus.charAt(r) == 'H')
		{
			digitalWrite(cmdRelaisPin[r], cmdRelaisEtatOn);     // Faire tirer le relais
		}
		else
		{
			//Serial.println("Relais OFF");
			digitalWrite(cmdRelaisPin[r], !cmdRelaisEtatOn);     // Faire tomber le relais
		}
	}
}

void relEtatList() // Lister l'état des relais
{
	Serial.println(F("\nEat des relais"));

	for (int r = 0; r < cmdRelaisNombre; r ++)     // Initialisation des pin des relais
	{
		Serial.print((digitalRead(cmdRelaisPin[r]) == cmdRelaisEtatOn) ? "1" : "0");
	}
	Serial.println("");
}

void relAllOff()  // En cas de perte de la liaison BT tout les relais à DOWN
{
	Serial.println(F("Tout les relais OFF"));
	for (int r = 0; r < cmdRelaisNombre; r ++)     // Initialisation des pin des relais
	{
		digitalWrite(cmdRelaisPin[r], !cmdRelaisEtatOn);     // Faire tomber le relais
	}
	relEtatList();
}
//------------------------------------- Display informations du programme
void sysInfo()
{
	Serial.println(F("\nCommande de fauteuil roulant"));
	Serial.println("\tRelais:\t\t" + String(cmdRelaisNombre));
	Serial.println("\tImpuls.:\t" + String(btWatchdogTempo));
	Serial.println("\tBluetooth:\t" + btNom);
}

//------------------------------------- LED de signalisation
void signLedDisplay(int ledIndex, int colorIndex, int timeDispl)
{
	signLed.setPixelColor(ledIndex, signLedColors[colorIndex]);
	signLed.show();

	if (timeDispl > 0)     // Si timeDispol > 0 millisec.
	{
		delay(timeDispl);
		signLed.setPixelColor(ledIndex, signLedColors[signColOff]);
		signLed.show();
	}
}

//------------------------------------- Commande de la LED warning
void signLedWarning(int ledLoop, unsigned long ledTime)     // Commande de la LED de warning
{
	for (int l = 0; l < (ledLoop *2); l ++)
	{
		if (l % 2 == 0)     // Une fois sur deux
		{
			signLedDisplay(signLedFctInfo, signColRed, ledTime);
		}
		else
		{
			signLedDisplay(signLedFctInfo, signColOff, ledTime);
		}
	}
	signLed.setPixelColor(signLedFctInfo, signLedColors[signColGreen]);
	signLed.show();
}

void signledTest(String ledCmd)     // Test des LED LED01R pour LED 1 en rouge
{
	Serial.println(ledCmd);
	int ledNum = ledCmd.substring(0, 2).toInt();
	String ledCouleur = ledCmd.substring(2);
	Serial.println(ledCouleur + "*");
	if (ledCouleur == "R")
	{
		signLedDisplay(ledNum, signColRed, 3000);
	}
	else if (ledCouleur == "V")
	{
		signLedDisplay(ledNum, signColGreen, 3000);
	}
	else if (ledCouleur == "B")
	{
		signLedDisplay(ledNum, signColBlue, 3000);
	}
	else
	{
		signLedDisplay(ledNum, signColOff, 3000);
	}
}

void signLedInitialisation()
{
	signLedColors[signColRed] = signLed.Color(255, 0, 0);     // Définition des couleurs
	signLedColors[signColGreen] = signLed.Color(0, 255, 0);
	signLedColors[signColBlue] = signLed.Color(0, 0, 255);
	signLedColors[signColYellow] = signLed.Color(255, 255, 0);
	signLedColors[signColOrange] = signLed.Color(255, 165, 0);
	signLedColors[signColWithe] = signLed.Color(255, 255, 255);
	signLedColors[signColOff] = signLed.Color(0, 0, 0);

	signLed.begin();
	signLed.setBrightness(signLebBrightMax);
}

Cordialement
jpbbricole

Hello hello,

C'est magnifique. Je reviens après avoir lu l'autre topic. Très beau projet. Félicitations à @jpbbricole pour son investissement et la réussite.

Je pense qu'il serait judicieux de demander à rouvrir le précédent topic pour continuer sur ce dernier plutôt que d'en ouvrir un nouveau. Ainsi tout sera au même endroit

J'avais fait il y a un bout de temps une application avec APP Inventor aussi, qui prenait en compte la reconnaissance vocal pour la saisie de texte au sein de l'application. Je dis ceci car peut-être qu'il serait intéressant d'utiliser l'assitant vocal en local plutôt que de passer par le cloud. Suivant le texte compris par l'assistant, ça active un bouton ou un autre.
Mais d'un autre côté, le cloud permettrait de commander le fauteuil depuis d'autres interfaces (utile ou pas ?)

En vous souhaitant un bon courage !!

Bonjour Anthony_P

Merci pour le compliment!
@foufouner est un "collaborateur" on ne peut plus efficace :wink:

C'était mon idée première, mais @foufouner s'est complément investi dans Google Home, qu'il maîtrise, on va intégrer ce projet dans cet environnement.

Bonne après-midi
jpbbricole

C'est du travail de pro, et très suisse :wink: (propre, carré, précis).

Chapeau.

Bonsoir @jef59

Merci, on ne peut renier ses origines :wink:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.