I am working on a project that I am using both AdaFruit Neopixel and Neomatrix.
For the Neopixel part I have a strip that turned on in the setup and used as a backlight. So it is a set and forget, but I would like to be able to have the flexibilty of changing the color/brightness down the road. The Neomatrix is connected to a 8x32 WS2812 display for scrolling messages. running on a Waveshare esp-c3zero, using different GPIO's to control 2 led segments.
The issue I have is when the sketch starts, the backlight comes on as expected, but when the matrix starts a second later it turns off the backlight.
I am almost certain the sketch is ok, I have tried various different variations of calling the backlight with in the sketch. But I am not a great(or good) programmer, so maybe I don't know what I don't know. At best I can get the backlight to flash if I put in it the matrix loop.
So knowing that the Neomatrix uses Neopixel - is this the expected behavior? or should I be able to run the 2 LED's in tandem?
Welcome to the forum
Do you think that it might help if you posted your full sketch, using code tags when you do, of course ?
There is a chance that it might also help if you posted a schematic of your project showing all components, how they are connected and powered
I will leave it to you to decide
Is contradicted by:
Do you set the LEDs within this strip to different colors or intensities from each other? If not, that's a rather expensive backlight. Consider switching to an analog strip and control the brightness with a single FET driven by a PWM output.
This is possible. Making text scroll might be in a MD Parolla library.
Color is a matter of addressing the WS2812 (rows * cols + cols) and updating the r, g, and b.
Brightness can be increased only if the initial color values are lower than maximum (255).
You can make every ws2812 do whatever you want... here is a sketch (a bit clumsy, but works for what it is for) for two "eyes" and a "halo" for a mask in a window... One eye stays green, the second eye has a random, red, "LASER pulse" and the halo glows from dim to bright....
#include <Adafruit_NeoPixel.h> // https://github.com/adafruit/Adafruit_NeoPixel
// https://adafruit.github.io/Adafruit_NeoPixel/html/class_adafruit___neo_pixel.html
#define PIN 6 // nano D6
#define PIX 3 // number of WS2812
Adafruit_NeoPixel pixel(PIX, PIN, NEO_GRB + NEO_KHZ800);
#define EYE2 2 // right eye is on Pix 2
#define EYE1 1 // left eye on Pix 1
#define HAL0 0 // HAL0 on Pix 0
unsigned long timerEYE1, timeoutEYE1, timerHAL0, timeoutHAL0 = 25;
int val = 15, dir = 1;
bool timeoutEYE1Created;
void setup() {
// Serial.begin(115200);
randomSeed(analogRead(A0));
pixel.begin();
pixel.clear();
pixel.show();
pixel.setPixelColor(EYE1, pixel.Color(0, 255, 0));
pixel.setPixelColor(EYE2, pixel.Color(0, 255, 0));
pixel.show();
}
void loop() {
eyePulse();
haloFade();
}
void haloFade() {
byte step = 2;
if (millis() - timerHAL0 > timeoutHAL0) {
timerHAL0 = millis();
val += (step * dir);
if (val > (255 - step) || val < (10 + step))
dir = -dir;
pixel.setPixelColor(HAL0, pixel.Color(val, val, val));
pixel.show();
}
}
void eyePulse() {
int pulsetime = 100;
if (!timeoutEYE1Created) { // create a random timeout
timeoutEYE1Created = 1;
timeoutEYE1 = random(5000, 10000);
}
if (millis() - timerEYE1 > timeoutEYE1) {
timeoutEYE1Created = 0;
timerEYE1 = millis();
pixel.setPixelColor(EYE2, pixel.Color(255, 0, 0)); // red
pixel.show();
delay(pulsetime);
pixel.setPixelColor(EYE2, pixel.Color(0, 255, 0)); // green
pixel.show();
delay(pulsetime);
pixel.setPixelColor(EYE2, pixel.Color(255, 0, 0)); // red
pixel.show();
delay(pulsetime);
pixel.setPixelColor(EYE2, pixel.Color(0, 255, 0)); // green
}
}
You can use a range of ws2812, rather than one.
diagram.json for the wokwi.com nerds
{
"version": 1,
"author": "Anonymous maker",
"editor": "wokwi",
"parts": [
{ "type": "wokwi-arduino-nano", "id": "nano", "top": 14.4, "left": -0.5, "attrs": {} },
{
"type": "wokwi-neopixel",
"id": "rgb1",
"top": -67.2,
"left": 60.3,
"rotate": 90,
"attrs": { "label": "halo" }
},
{
"type": "wokwi-neopixel",
"id": "rgb2",
"top": -28.8,
"left": 31.5,
"rotate": 90,
"attrs": {}
},
{
"type": "wokwi-neopixel",
"id": "rgb3",
"top": -28.8,
"left": 89.1,
"rotate": 90,
"attrs": {}
}
],
"connections": [
[ "nano:6", "rgb1:DIN", "green", [ "v0" ] ],
[ "rgb1:VDD", "rgb3:VDD", "red", [ "v-19.2", "h38.4" ] ],
[ "rgb1:VDD", "rgb2:VDD", "red", [ "v-19.2", "h-28.8" ] ],
[ "nano:5V.2", "rgb3:VDD", "red", [ "v0", "h-28.8", "v-144", "h-9.6" ] ],
[ "nano:GND.3", "rgb2:VSS", "black", [ "v0", "h-105.6" ] ],
[ "rgb1:DOUT", "rgb3:DIN", "green", [ "v-9.6", "h48.9", "v76.8", "h-9.6" ] ],
[ "rgb3:DOUT", "rgb2:DIN", "green", [ "v-9.6", "h-37.5", "v38.4", "h-9.6" ] ],
[ "rgb1:VSS", "rgb3:VSS", "black", [ "h0.9", "v56.8", "h19.2" ] ],
[ "rgb1:VSS", "rgb2:VSS", "black", [ "h0.9", "v56.8", "h-19.2" ] ]
],
"dependencies": {}
}
[UKHeliBob ] -thanks for the welcome, long time reader- first time poster. I can certainly post the code and schematic later tonight, but it was a the general question of should it work?
gfvalvo - LOL yeah, my life is a contradiction.. I say I think it is ok because it is known examples glued together and each works on its own, and everything else works with the exception of the backlights shutting off.
my choice of the neopixel strip based on size and function, I have limited space where they go, and I wanted color change. Cost was $20 for a 300+ LED strip, so really not expensive, I bought them more to make the matrix, and had extras, so why not try and use them.
We need to know the details of "it"
You can certainly control 2 Neopixel strips in a single sketch but the devil is in the detail of the hardware and software
It is totally impossible to tell unless we see if you have made any mistakes combining the two working sketches.
Or if you have made any fundamental mistakes in the concept of what you are doing.
ok so here is the project - code and sorry I had to do a block diagram for the schematic.
I built the sketch with tabs so the tabs are called out in the code listed here.
//TAB1 - SETUP and LOOP
#include <Adafruit_NeoPixel.h>
#include <DS3231.h>
#include <Wire.h>
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <LittleFS.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
int matrixW = 32;
int matrixH = 8;
const int SER_Pin = 2; // serial data input pin
const int SRCLK_Pin = 3; // shift register clock input pin
const int RCLK_Pin = 4; // storage register clock input pin
//#define PINN 9 // GPIO for Neopixel (backlight)
//#define PINM 8 // GPIO for Neomatrix
DS3231 myRTC;
bool h12Flag;
bool pmFlag;
const int displayCount = 4; // number of 7-segment displays
const byte digitFont[] = { // seven segment display font for digits 0 to 9
0b01111110, // 0
0b00000110, // 1
0b01101101, // 2
0b01111001, // 3
0b00110011, // 4
0b01011011, // 5
0b11011111, // 6
0b01110000, // 7
0b01111111, // 8
0b01110011 // 9
};
byte displayData[displayCount] = { // data for each display
0, 0, 0, 0
};
Adafruit_NeoMatrix matrix(matrixW, matrixH, 8,
NEO_MATRIX_BOTTOM + NEO_MATRIX_LEFT +
NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
NEO_RGB + NEO_KHZ800);
#define BRIGHTNESS 5
Adafruit_NeoPixel npixels(8, 9, NEO_RGB + NEO_KHZ800);
const char* ssid = "******";
const char* password = "********";
const char* PARAM_STRING = "inputString";
const char* PARAM_INT = "inputInt";
const char* PARAM_FLOAT = "inputFloat";
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>ESP Input Form</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
function submitMessage() {
alert("Saved value to ESP LittleFS");
setTimeout(function(){ document.location.reload(false); }, 500);
}
</script></head><body>
<h1>Clock Text Message</h1>
<form action="/get" target="hidden-form">
inputString (current value %inputString%): <input type="text" name="inputString">
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
inputInt (current value %inputInt%): <input type="number " name="inputInt">
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
inputFloat (current value %inputFloat%): <input type="number " name="inputFloat">
<input type="submit" value="Submit" onclick="submitMessage()">
</form>
<iframe style="display:none" name="hidden-form"></iframe>
</body></html>)rawliteral";
const uint16_t colors[] = {
matrix.Color(0, 255, 0), matrix.Color(0, 255, 0), matrix.Color(255, 255, 0), matrix.Color(0, 0, 255), matrix.Color(255, 0, 255), matrix.Color(0, 255, 255), matrix.Color(255, 255, 255)
};
#define arr_len( x ) ( sizeof( x ) / sizeof( *x ) ) // Calculation of Array Size;
int pixelPerChar = 6; // Width of Standard Font Characters is 8X6 Pixels
int x = matrix.width(); // Width of the Display
int pass = 0; // Counter
int i = 0; // Counter
int clr = 0; // Counter for Indexing Array of Colors
char msg[] = "test message"; // BLANK Message of Your Choice;
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
String readFile(fs::FS &fs, const char * path){
Serial.printf("Reading file: %s\r\n", path);
File file = fs.open(path, "r");
if(!file || file.isDirectory()){
Serial.println("- empty file or failed to open file");
return String();
}
Serial.println("- read from file:");
String fileContent;
while(file.available()){
fileContent+=String((char)file.read());
}
file.close();
Serial.println(fileContent);
return fileContent;
}
String processor(const String& var){
//Serial.println(var);
if(var == "inputString"){
return readFile(LittleFS, "/inputString.txt");
}
else if(var == "inputInt"){
return readFile(LittleFS, "/inputInt.txt");
}
else if(var == "inputFloat"){
return readFile(LittleFS, "/inputFloat.txt");
}
return String();
}
void setup() {
pinMode(SER_Pin, OUTPUT);
pinMode(SRCLK_Pin, OUTPUT);
pinMode(RCLK_Pin, OUTPUT);
Wire.begin(0,1);
Serial.begin(115200);
matrix.begin();
npixels.begin();
delay (1000);
npixels.setPixelColor(1, npixels.Color(0, 0, 150));
npixels.setPixelColor(2, npixels.Color(0, 0, 150));
npixels.setPixelColor(3, npixels.Color(0, 0, 150));
npixels.setPixelColor(4, npixels.Color(0, 0, 150));
npixels.setPixelColor(5, npixels.Color(0, 0, 150));
npixels.setPixelColor(6, npixels.Color(0, 0, 150));
npixels.setPixelColor(7, npixels.Color(0, 0, 150));
npixels.setPixelColor(8, npixels.Color(0, 0, 150));
npixels.show();
matrix.setTextWrap(false);
matrix.setBrightness(5);
matrix.setTextColor(colors[0]);
// Initialize LittleFS
#ifdef ESP32
if(!LittleFS.begin(true)){
Serial.println("An Error has occurred while mounting LittleFS");
return;
}
#else
if(!LittleFS.begin()){
Serial.println("An Error has occurred while mounting LittleFS");
return;
}
#endif
delay(1000);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed!");
return;
}
Serial.println();
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// Send web page with input fields to client
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/get?inputString=<inputMessage>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET inputString value on <ESP_IP>/get?inputString=<inputMessage>
if (request->hasParam(PARAM_STRING)) {
inputMessage = request->getParam(PARAM_STRING)->value();
writeFile(LittleFS, "/inputString.txt", inputMessage.c_str());
}
// GET inputInt value on <ESP_IP>/get?inputInt=<inputMessage>
else if (request->hasParam(PARAM_INT)) {
inputMessage = request->getParam(PARAM_INT)->value();
writeFile(LittleFS, "/inputInt.txt", inputMessage.c_str());
}
// GET inputFloat value on <ESP_IP>/get?inputFloat=<inputMessage>
else if (request->hasParam(PARAM_FLOAT)) {
inputMessage = request->getParam(PARAM_FLOAT)->value();
writeFile(LittleFS, "/inputFloat.txt", inputMessage.c_str());
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/text", inputMessage);
});
server.onNotFound(notFound);
server.begin();
}
void loop() {
updateDisplay((myRTC.getHour(h12Flag, pmFlag)), myRTC.getMinute());
fiber();
}
.//TAB 2 - MATRIX CONTROL
// Adafruit_NeoMatrix example for single NeoPixel Shield.
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <LittleFS.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
// HTML web page to handle 3 input fields (inputString, inputInt, inputFloat)
void fiber() {
String yourInputString = readFile(LittleFS, "/inputString.txt");
Serial.print("*** Your inputString: ");
Serial.println(yourInputString);
int yourInputInt = readFile(LittleFS, "/inputInt.txt").toInt(); //not currently used in sketch
Serial.print("*** Your inputInt: ");
Serial.println(yourInputInt);
float yourInputFloat = readFile(LittleFS, "/inputFloat.txt").toFloat();//not currently used in sketch
Serial.print("*** Your inputFloat: ");
Serial.println(yourInputFloat);
// delay(5000);
display_scrollText() ;
}
void writeFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Writing file: %s\r\n", path);
File file = fs.open(path, "w");
if(!file){
Serial.println("- failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("- file written");
} else {
Serial.println("- write failed");
}
file.close();
}
void display_scrollText() {
String yourInputString = readFile(LittleFS, "/inputString.txt");
int j= yourInputString.length();
Serial.println(j);
int arrSize = arr_len( colors );
// char* exampleText[] = ConvertStringToCharArray (yourInputString); // SCROLLING Message of Your Choice;
writeText(yourInputString);
delay(100);
matrix.print(msg); //Print the Message String;
matrix.show();
delay(100);
/* Commands for Debugging
char msgText[] = "Let's Start Over";
matrix.print(msgText); // Scrolling Print the Message String;
matrix.show();
delay(1000);
writeText("End of Loop"); //Print the Message String;
delay(1000);
*/
}
void writeText(String msg) {
int arrSize = arr_len( colors ); // Array of Text Colors;
int msgSize = (msg.length() * pixelPerChar) + (2 * pixelPerChar); // CACULATE message length;
int scrollingMax = (msgSize) + matrix.width(); // ADJUST Displacement for message length;
x = matrix.width(); // RESET Cursor Position and Start Text String at New Position on the Far Right;
clr = 0; // RESET Color/Repeat Index;
while (clr <= arrSize) {
/* Change Color with Each Pass of Complete Message */
matrix.setTextColor(colors[clr]);
matrix.fillScreen(0); // BLANK the Entire Screen;
matrix.setCursor(x, 0); // Set Starting Point for Text String;
matrix.print(msg); // Set the Message String;
/* SCROLL TEXT FROM RIGHT TO LEFT BY MOVING THE CURSOR POSITION */
if (--x < -scrollingMax ) {
/* ADJUST FOR MESSAGE LENGTH */
// Decrement x by One AND Compare New Value of x to -scrollingMax;
// This Animates (moves) the text by one pixel to the Left;
x = matrix.width(); // After Scrolling by scrollingMax pixels, RESET Cursor Position and Start String at New Position on the Far Right;
++clr; // INCREMENT COLOR/REPEAT LOOP COUNTER AFTER MESSAGE COMPLETED;
}
matrix.show(); // DISPLAY the Text/Image
delay(40); // SPEED OF SCROLLING or FRAME RATE;
}
clr = 0; // Reset Color/Loop Counter;
\
}
// TAB 3 - CLOCK
#include <DS3231.h>
#include <Wire.h>
void updateDisplay(int hours, int minutes) {
// update displayData array with new values
displayData[0] = digitFont[minutes % 10];
displayData[1] = digitFont[minutes / 10];
displayData[2] = digitFont[hours % 10];
displayData[3] = digitFont[hours / 10];
// update all displays with new data
for (int i = 0; i < 4; i++){
shiftOut(SER_Pin, SRCLK_Pin, LSBFIRST, displayData[i]); // send data for this display
digitalWrite(RCLK_Pin, HIGH); // set storage register clock input high
delay(1); // delay to avoid ghosting
//Serial.println (i);
digitalWrite(RCLK_Pin, LOW); // set storage register clock input low
if (i==3){(delay (1000));}
else{
Serial.print(myRTC.getHour(h12Flag, pmFlag),(DEC));
Serial.print(":");
Serial.println( myRTC.getMinute());
}
That is not the way to wire up neopixels. You have no series resistor, nor any capacitors on the output.
see The Magic of NeoPixels | Adafruit NeoPixel Überguide | Adafruit Learning System
You have multiple programs in one code block. Please, put each in its own code block.