En aquest exemple controlarem el color d'un NeoPixel des d'una aplicació mòbil fent servir MQTT. En aquest cas, a més del programa del microcontrolador, ens caldrà configurar l'aplicació per poder fer la interacció. El programa del microcontrolador seria el que surt a continuació i que més endavant comentarem. Aquest programa és semblant al de l'exemple del LED però amb alguns canvis.
// Està parcialment basat en programes de Demetrio Pina i Fábio Souza #include <SPI.h> // Carreguem la biblioteca SPI #include <WiFiNINA.h> // Carreguem la biblioteca WiFiNINA #include <PubSubClient.h> // Biblioteca per a MQTT #include <Adafruit_NeoPixel.h>
const char idXarxa[] = "xarxa-wifi"; // Nom del punt d'accés const char contrasenya[] = "contrasenya-wifi"; // Contrasenya de connexió const char servidor[] = "broker.mqtt-dashboard.com"; // Contrasenya de connexió WiFiClient clientwifi; // Client Wi-Fi PubSubClient client(clientwifi); // Client MQTT Adafruit_NeoPixel cadena = Adafruit_NeoPixel(1, 1, NEO_GRB + NEO_KHZ800); byte R, G, B; // Els tres colors per al NeoPixel
void connecta_xarxa() {
delay(1000);
Serial.print("Connectant a la xarxa ");
Serial.println(idXarxa);
WiFi.begin(idXarxa, contrasenya);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.print("Connectat!");
Serial.print("Adreça IP: ");
Serial.println(WiFi.localIP());
}
// Aquesta funció s'executarà automàticament quan es detecti un canvi
void callback(char* topic, byte* payload, unsigned int length) {
int valor = 0;
char estat[25]; // Aquí hi posarem l'estat (RGB) del NeoPixel
// Suposem que no arribarem a 25 caràcters
String etiq((char*)topic); // Convertim l'etiqueta (topic) a String
String enviar = ""; // Text que enviarem amb l'estat del NeoPixel
String rebut = ""; // Aquí hi posarem el valor rebut (payload) convertit a String
Serial.print("Topic: ");
Serial.println(topic);
for (int i = 0; i < length; i++){
rebut = rebut + (char)payload[i]; // Passem payload a String
}
valor = rebut.toInt(); // I ho convertim en un enter
Serial.print("Payload: ");
Serial.println(valor);
if (valor < 0){
valor = 0;
}
if (valor > 255){
valor = 255;
}
if (etiq == "oba_neopixel_R"){
R = valor; // Si l'etiqueta correspon a vermell, ho guardem a R
}
if (etiq == "oba_neopixel_G"){
G = valor; // Si l'etiqueta correspon a verd, ho guardem a G
}
if (etiq == "oba_neopixel_B"){
B = valor; // Si l'etiqueta correspon a blau, ho guardem a B
}
cadena.setPixelColor(0, R, G, B); // Posa el color
cadena.show(); // Actualitza
enviar = enviar + "R = " + R + "\n" + "G = " + G + "\n" + "B = " + B;
enviar.toCharArray(estat, 25); // Cal convertir enviar a char
client.publish("oba_estat_neopixel", estat); // Ho enviem al servidor
}
void connecta_mqtt() {
while (!client.connected()) {
Serial.println("Connectant al servidor MQTT");
if (client.connect("oba_mqtt")) {
Serial.println("Connectat!");
client.subscribe("oba_neopixel_R");
client.subscribe("oba_neopixel_G");
client.subscribe("oba_neopixel_B");
} else {
Serial.println("Ha fallat la connexió!");
Serial.print("Resposta = ");
Serial.println(client.state());
delay(5000);
}
}
}
void setup() { // Inicialització
Serial.begin(9600);
cadena.begin(); // Inicialitza els NeoPixels
cadena.show();
connecta_xarxa();
client.setServer(servidor, 1883);
client.setCallback(callback);
}
void loop() { // Programa que es repeteix indefinidament
if (!client.connected()) {
connecta_mqtt();
}
client.loop(); // Consulta el servidor MQTT
}
Respecte a l'exemple del LED, observem que ara es subscriuen tres etiquetes, una per a cada color, amb les que rebrem el valor (entre 0 i 255) per a vermell, blau o verd. La resta de canvis importants estan a la funció callback.
Atès que rebrem informacions corresponents, indistintament, a qualsevol de les tres etiquetes, caldrà mirar quina etiqueta hem rebut a cada moment. Ara el valor rebut no serà només un caràcter i, per tant, haurem de mirar quants caracters hem rebut (paràmetre length de la funció) i convertir els caràcters primer en un char, després en un String i finalment en un valor enter. Serà convenient comprovar que el valor rebut està entre 0 i 255, el rang que admet cada component de color del NeoPixel. El valor rebut el guardarem en el color corresponent (els altres no canviaran) i actualitzarem el color del NeoPixel. També prepararem un text per enviar a l'aplicació. El prepararem com a String, ja que és més fàcil, però després l'haurem de passar a char.
Un cop tenim fet el programa per al microcontrolador, cal preparar l'aplicació per tal que es puguin comunicar. En aquesta pàgina podem trobar informació més general sobre l'ús de l'aplicació. Per a aquest exemple en concret, cal crear un espai per al projecte picant al botó ⊕ i deixant la majoria de paràmetres per defecte. Només haurem d'editar els següents:
| Paràmetre | Exemple | Comentaris |
| Name | Control NeoPixel | Qualsevol nom que ens permeti diferenciar el projecte dels altres |
| Address | broker.mqtt-dashboard.com | Adreça del servidor MQTT que fem servir |
| Port | 1883 | Port emprat pel servidor, el normal és 1883 |
Després d'acabar la configuració, picarem sobre la icona
![]()
Dins del projecte posarem quatre elements. Tres entrades de text (text) per ajustar els colors i un text (text) per mostrar-ne els valors en cada moment. Els paràmetres que hem de configurar a cada text són:
| Text | Paràmetre | Exemple | Comentaris |
| Valors | Name | NeoPixel | Qualsevol nom que ens permeti diferenciar aquest element d'altres similars |
| Topic (sub) | oba_estat_neopixel | L'etiqueta que hem posat al programa | |
| Main text size | Small | Mida de la lletra del text que es mostrarà | |
| Main text color | ◼ | Color de la lletra del text que es mostrarà | |
| Vermell | Name | R | |
| Topic (sub) | oba_neopixel_R | L'etiqueta que hem posat al programa | |
| Main text size | Medium | Mida de la lletra del text que es mostrarà | |
| Main text color | ◼ | Color de la lletra del text que es mostrarà | |
| Verd | Name | G | |
| Topic (sub) | oba_neopixel_G | L'etiqueta que hem posat al programa | |
| Main text size | Medium | Mida de la lletra del text que es mostrarà | |
| Main text color | ◼ | Color de la lletra del text que es mostrarà | |
| Blau | Name | B | |
| Topic (sub) | oba_neopixel_B | L'etiqueta que hem posat al programa | |
| Main text size | Medium | Mida de la lletra del text que es mostrarà | |
| Main text color | ◼ | Color de la lletra del text que es mostrarà |
Després d'acabar la configuració, picarem sobre la icona
![]()
L'aspecte dels botons de l'aplicació serà el que es mostra a la imatge següent. En picar en un dels requadres, podrem entrar-hi un nou valor.
Farem una nova versió en la que, en lloc d'entrar els tres valors en format text, seleccionarem les components de color amb selectors de rang. Atès que ara el selector només ens permetrà l'entrada de valors dins el rang establert, el programa és una mica més senzill ja que no cal comprovar que els valors rebuts siguin correctes. Per mostrar el color que s'envia al NeoPixel farem servir un element color, això farà necessari enviar les dades en el format hexadecimal de sis xifres que es fa servir en html. Per exemple, per enviar el color groc seria #ffff00.
// Està parcialment basat en programes de Demetrio Pina i Fábio Souza #include <SPI.h> // Carreguem la biblioteca SPI #include <WiFiNINA.h> // Carreguem la biblioteca WiFiNINA #include <PubSubClient.h> // Biblioteca per a MQTT #include <Adafruit_NeoPixel.h>
const char idXarxa[] = "xarxa-wifi"; // Nom del punt d'accés const char contrasenya[] = "contrasenya-wifi"; // Contrasenya de connexió const char servidor[] = "broker.mqtt-dashboard.com"; // Contrasenya de connexió WiFiClient clientwifi; // Client Wi-Fi PubSubClient client(clientwifi); // Client MQTT Adafruit_NeoPixel cadena = Adafruit_NeoPixel(1, 1, NEO_GRB + NEO_KHZ800); byte R, G, B; // Els tres colors per al NeoPixel
void connecta_xarxa() {
delay(1000);
Serial.print("Connectant a la xarxa ");
Serial.println(idXarxa);
WiFi.begin(idXarxa, contrasenya);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.print("Connectat!");
Serial.print("Adreça IP: ");
Serial.println(WiFi.localIP());
}
// Aquesta funció s'executarà automàticament quan es detecti un canvi
void callback(char* topic, byte* payload, unsigned int length) {
int valor = 0;
char estat[25]; // Aquí hi posarem l'estat (RGB) del NeoPixel
// Suposem que no arribarem a 25 caràcters
String etiq((char*)topic); // Convertim l'etiqueta (topic) a String
String enviar = "#"; // Text que enviarem amb l'estat del NeoPixel
String rebut = ""; // Aquí hi posarem el valor rebut (payload) convertit a String
Serial.print("Topic: ");
Serial.println(topic);
for (int i = 0; i < length; i++){
rebut = rebut + (char)payload[i]; // Passem payload a String
}
valor = rebut.toInt(); // I ho convertim en un enter
Serial.print("Payload: ");
Serial.println(valor);
if (etiq == "oba_neopixel_R"){
R = valor; // Si l'etiqueta correspon a vermell, ho guardem a R
}
if (etiq == "oba_neopixel_G"){
G = valor; // Si l'etiqueta correspon a verd, ho guardem a G
}
if (etiq == "oba_neopixel_B"){
B = valor; // Si l'etiqueta correspon a blau, ho guardem a B
}
cadena.setPixelColor(0, R, G, B); // Posa el color
cadena.show(); // Actualitza
if (R < 16){ // Si és menor de 16
enviar = enviar + "0"; // Afegim el 0
}
enviar = enviar + String(R, HEX);
if (G < 16){ // Si és menor de 16
enviar = enviar + "0"; // Afegim el 0
}
enviar = enviar + String(G, HEX);
if (B < 16){ // Si és menor de 16
enviar = enviar + "0"; // Afegim el 0
}
enviar = enviar + String(B, HEX);
enviar.toCharArray(estat, 25); // Cal convertir enviar a char
client.publish("oba_estat_neopixel", estat); // Ho enviem al servidor
}
void connecta_mqtt() {
while (!client.connected()) {
Serial.println("Connectant al servidor MQTT");
if (client.connect("oba_mqtt")) {
Serial.println("Connectat!");
client.subscribe("oba_neopixel_R");
client.subscribe("oba_neopixel_G");
client.subscribe("oba_neopixel_B");
} else {
Serial.println("Ha fallat la connexió!");
Serial.print("Resposta = ");
Serial.println(client.state());
delay(5000);
}
}
}
void setup() { // Inicialització
Serial.begin(9600);
cadena.begin(); // Inicialitza els NeoPixels
cadena.show();
connecta_xarxa();
client.setServer(servidor, 1883);
client.setCallback(callback);
}
void loop() { // Programa que es repeteix indefinidament
if (!client.connected()) {
connecta_mqtt();
}
client.loop(); // Consulta el servidor MQTT
}
Un cop tenim fet el programa per al microcontrolador, cal preparar l'aplicació per tal que es puguin comunicar. En aquesta pàgina podem trobar informació més general sobre l'ús de l'aplicació. Per a aquest exemple en concret, cal crear un espai per al projecte picant al botó ⊕ i deixant la majoria de paràmetres per defecte. Només haurem d'editar els següents:
| Paràmetre | Exemple | Comentaris |
| Name | Control NeoPixel | Qualsevol nom que ens permeti diferenciar el projecte dels altres |
| Address | broker.mqtt-dashboard.com | Adreça del servidor MQTT que fem servir |
| Port | 1883 | Port emprat pel servidor, el normal és 1883 |
Després d'acabar la configuració, picarem sobre la icona
![]()
Dins del projecte posarem quatre elements. Tres selectors de rang (range/progress) per ajustar els colors i un color (color) per mostrar el color enviat en cada moment. En el cas dels selectors de rang, els paràmetres que hem de configurar són:
| Selector | Paràmetre | Exemple | Comentaris |
| Vermell | Name | R | |
| Topic (sub) | oba_neopixel_R | L'etiqueta que hem posat al programa | |
| Min | 0.0 | Valor mínim del rang | |
| Max | 255.0 | Valor mínim del rang | |
| Progress color | ◼ | Color del selector | |
| Verd | Name | G | |
| Topic (sub) | oba_neopixel_G | L'etiqueta que hem posat al programa | |
| Min | 0.0 | Valor mínim del rang | |
| Max | 255.0 | Valor mínim del rang | |
| Progress color | ◼ | Color del selector | |
| Blau | Name | B | |
| Topic (sub) | oba_neopixel_B | L'etiqueta que hem posat al programa | |
| Min | 0.0 | Valor mínim del rang | |
| Max | 255.0 | Valor mínim del rang | |
| Progress color | ◼ | Color del selector |
Després d'acabar la configuració, picarem sobre la icona
![]()
Els paràmetres que hem de configurar al color són:
| Paràmetre | Exemple | Comentaris |
| Name | NeoPixel | Qualsevol nom que ens permeti diferenciar aquest element d'altres similars |
| Topic (sub) | oba_estat_neopixel | L'etiqueta que hem posat al programa |
| Payload format | HEX string | Format en el que es rebran les dades |
| Icon | ![]() |
Icona sobre la que es mostrarà el color |
Després d'acabar la configuració, picarem sobre la icona
![]()
L'aspecte dels botons de l'aplicació serà el que es mostra a la imatge següent. En picar en un dels selectors, podrem ajustar-ne el valor desplaçant el disc que fa de punter.
Farem una tercera versió en la que, en lloc d'entrar els tres valors individualment, seleccionarem un color amb un selector de color. El selector enviarà el color en format hexadecimal i, per tant, caldrà convertir-lo a tres components decimals. Per mostrar el color que s'envia al NeoPixel farem servir un element text. Ara només caldrà subscriure una etiqueta.
// Està parcialment basat en programes de Demetrio Pina i Fábio Souza #include <SPI.h> // Carreguem la biblioteca SPI #include <WiFiNINA.h> // Carreguem la biblioteca WiFiNINA #include <PubSubClient.h> // Biblioteca per a MQTT #include <Adafruit_NeoPixel.h>
const char idXarxa[] = "xarxa-wifi"; // Nom del punt d'accés const char contrasenya[] = "contrasenya-wifi"; // Contrasenya de connexió const char servidor[] = "broker.mqtt-dashboard.com"; // Contrasenya de connexió WiFiClient clientwifi; // Client Wi-Fi PubSubClient client(clientwifi); // Client MQTT Adafruit_NeoPixel cadena = Adafruit_NeoPixel(1, 1, NEO_GRB + NEO_KHZ800); byte R, G, B; // Els tres colors per al NeoPixel
byte HEXtoDEC(byte car){
byte res;
if((car >= 48) && (car <= 57)){ // Si està entre 0 i 9
res = car -48; // Restem el codi ASCII de 0
}
if((car >= 65) && (car <= 70)){ // Si està entre 10 i 15
res = car -65 +10; // Restem el codi ASCII de la lletra A i sumem 10
}
if((car >= 97) && (car <= 102)){ // Per si les lletres estan en minúscules
res = car -97 +10; // Restem el codi ASCII de la lletra a i sumem 10
}
return res;
}
void connecta_xarxa() {
delay(1000);
Serial.print("Connectant a la xarxa ");
Serial.println(idXarxa);
WiFi.begin(idXarxa, contrasenya);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.print("Connectat!");
Serial.print("Adreça IP: ");
Serial.println(WiFi.localIP());
}
// Aquesta funció s'executarà automàticament quan es detecti un canvi
void callback(char* topic, byte* payload, unsigned int length) {
char estat[25]; // Aquí hi posarem l'estat (RGB) del NeoPixel
// Suposem que no arribarem a 25 caràcters
String etiq((char*)topic); // Convertim l'etiqueta (topic) a String
String enviar = ""; // Text que enviarem amb l'estat del NeoPixel
Serial.print("Topic: ");
Serial.println(topic);
if (length >= 7){
R = HEXtoDEC(payload[1]) * 16 + HEXtoDEC(payload[2]);
G = HEXtoDEC(payload[3]) * 16 + HEXtoDEC(payload[4]);
B = HEXtoDEC(payload[5]) * 16 + HEXtoDEC(payload[6]);
Serial.print("R: ");
Serial.println(R);
Serial.print("G: ");
Serial.println(G);
Serial.print("B: ");
Serial.println(B);
cadena.setPixelColor(0, R, G, B); // Posa el color
cadena.show(); // Actualitza
}
enviar = enviar + "R = " + R + "\n" + "G = " + G + "\n" + "B = " + B;
enviar.toCharArray(estat, 25); // Cal convertir enviar a char
client.publish("oba_estat_neopixel", estat); // Ho enviem al servidor
}
void connecta_mqtt() {
while (!client.connected()) {
Serial.println("Connectant al servidor MQTT");
if (client.connect("oba_mqtt")) {
Serial.println("Connectat!");
client.subscribe("oba_neopixel_RGB");
} else {
Serial.println("Ha fallat la connexió!");
Serial.print("Resposta = ");
Serial.println(client.state());
delay(5000);
}
}
}
void setup() { // Inicialització
Serial.begin(9600);
cadena.begin(); // Inicialitza els NeoPixels
cadena.show();
connecta_xarxa();
client.setServer(servidor, 1883);
client.setCallback(callback);
}
void loop() { // Programa que es repeteix indefinidament
if (!client.connected()) {
connecta_mqtt();
}
client.loop(); // Consulta el servidor MQTT
}
Un cop tenim fet el programa per al microcontrolador, cal preparar l'aplicació per tal que es puguin comunicar. En aquesta pàgina podem trobar informació més general sobre l'ús de l'aplicació. Per a aquest exemple en concret, cal crear un espai per al projecte picant al botó ⊕ i deixant la majoria de paràmetres per defecte. Només haurem d'editar els següents:
| Paràmetre | Exemple | Comentaris |
| Name | Control NeoPixel | Qualsevol nom que ens permeti diferenciar el projecte dels altres |
| Address | broker.mqtt-dashboard.com | Adreça del servidor MQTT que fem servir |
| Port | 1883 | Port emprat pel servidor, el normal és 1883 |
Després d'acabar la configuració, picarem sobre la icona
![]()
Dins del projecte posarem dos elements. Un selector de color (color) i un per mostrar el text (text) per mostrar les components del color enviat en cada moment. En el cas del selector de color, els paràmetres que hem de configurar són:
| Paràmetre | Exemple | Comentaris |
| Name | Selector | Qualsevol nom que ens permeti diferenciar aquest element d'altres similars |
| Topic (sub) | oba_neopixel_RGB | L'etiqueta que hem posat al programa |
| Payload format | HEX string | Format en el que es rebran les dades |
| Icon | ![]() |
Icona sobre la que es mostrarà el color |
Després d'acabar la configuració, picarem sobre la icona
![]()
Els paràmetres que hem de configurar al text són:
| Paràmetre | Exemple | Comentaris |
| Name | NeoPixel | Qualsevol nom que ens permeti diferenciar aquest element d'altres similars |
| Topic (sub) | oba_estat_neopixel | L'etiqueta que hem posat al programa |
| Main text size | Small | Mida de la lletra del text que es mostrarà |
| Main text color | ◼ | Color de la lletra del text que es mostrarà |
Després d'acabar la configuració, picarem sobre la icona
![]()
L'aspecte dels botons de l'aplicació serà el que es mostra a la imatge següent. En picar en el selector de color, podrem triar el que desitgem.

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.