Ledstripmatrix
New member
Hello, i'm using an teensy 3.5(used 3.1 before) to control an led strip matrix which is 80*46 ish. But the matrix is acting weird, 1/4 down the matrix in the middle off a strip its just random colors for 1/3 then it's just black the rest. The first 1/4 is working but have some color issue.
I will attach a picture, and hopefully someone would be able to assist me.
https://imgur.com/lBxmUY5
https://imgur.com/SYXTBM8
Thanks a lot.
I will attach a picture, and hopefully someone would be able to assist me.
https://imgur.com/lBxmUY5
https://imgur.com/SYXTBM8
Thanks a lot.
Code:
/*
* This is a program designed to run on a Teensy at 48 MHz
* The program will display content on a X*Y LED screen built with WS2812 LEDs
* The program can display content form its own demo modes or get data over the serial port
* A switch desides where the conten should come from
* A potentiometer adjust the brightness of the screen
*/
int DATA = 2; // Data pin
int CLOCK = 3; // Clock pin
int DEMO = 4; // Demo mode switch
int DEMO_MODE = 5; // Demo mode chooser switch
int BRIGHTNESS_PIN = A0; // Potmeter pin
int demoState = 0; // State of demo mode
int lastState = 0; // Last demo mode state
int brightnessLevel = 0; // The brightness level of the screen
int logoPosX = 0; // The X position of the logo
int logoPosY = 0; // The Y position of the logo
int speedX = 1; // The X speed and direction of the logo
int speedY = 1; // The Y speed and direction of the logo
int swipePixel = 0; // Position of the swipe color
int byteReceived = 0; // Number of byte received
const int BOUNCE_LOGO = 0; // Bounce logo state
const int RANDOM_COLOR = 1; // Random color state
const int COLOR_SWIPE = 2; // Color swipe state
const int FILL_RANDOM = 3; // Fill random state
const int CHANGE_STATE = 4; // Change state state
const int PICTURE_Y = 40; // Y size of the screen
const int PICTURE_X = 80; // X size of the screen
boolean lastDemoMode = false;
boolean lastDemo = false;
boolean updateScreen = false;
boolean initColorSwipe = false;
boolean initFillRandom = false;
boolean initBounceLogo = false;
long pictureArray[3200]; // Picture array
long updateTime = 40; // Screen update time milli sec
unsigned long modeTime = 0; // Time for sending mode
unsigned long nextUpdateTime = 0; // Time to next update
unsigned long nextRandomColor = 0; // Time to next random color
long swipeColors[768]; // Array of swipe colors
long pictureMatrix[80][40]; // Picture matrix
// Logo matrix
long NTNU[8][8] = {
{0x000000, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x000000},
{0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF},
{0x0000FF, 0x0000FF, 0x000000, 0x000000, 0x000000, 0x000000, 0x0000FF, 0x0000FF},
{0x0000FF, 0x0000FF, 0x000000, 0x0000FF, 0x0000FF, 0x000000, 0x0000FF, 0x0000FF},
{0x0000FF, 0x0000FF, 0x000000, 0x0000FF, 0x0000FF, 0x000000, 0x0000FF, 0x0000FF},
{0x0000FF, 0x0000FF, 0x000000, 0x000000, 0x000000, 0x000000, 0x0000FF, 0x0000FF},
{0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF},
{0x000000, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x000000}
};
// Setup
void setup() {
pinMode(DATA, OUTPUT); // Sets the DATA pin as an output
pinMode(CLOCK, OUTPUT); // Sets the CLOCK pin as an output
pinMode(13, OUTPUT); // Sets the 13 pin as an output
pinMode(DEMO, INPUT); // Sets the DEMO pin as an input
pinMode(DEMO_MODE, INPUT); // Sets the DEMO_MODE pin as an input
pinMode(BRIGHTNESS_PIN, INPUT); // Sets the BRIGHTNESS_PIN pin as an input
Serial.begin(38400); // Starts serial communication at 38400 baudrate
clearMatrix(); // Clears the matrix
randomSeed(analogRead(A1)); // Initialize the random function with a value from an unused analog input
nextUpdateTime = millis(); // Set initial value to nextUpodateTime
modeTime = millis(); // Set initial value to modeTime
}
// Loop. Runs over and over
void loop() {
writeMode(); // Calls the writeMode function
int level = analogRead(BRIGHTNESS_PIN); // Read the value of the potmeter
brightnessLevel = map(level, 0, 1023, 0, 3); // Map the level to desired value
if (millis() >= nextUpdateTime) {
updateScreen = true;
nextUpdateTime += updateTime;
digitalWrite(13, HIGH); // Used for visual feedback
}
else {
updateScreen = false;
digitalWrite(13, LOW); // Used for visual feedback
}
if (digitalRead(DEMO)) {
demo(); // Calls the demo function
if (updateScreen) {
writeScreen(); // Calls the writeScreen function
}
}
else {
if (Serial.available() == 0) {
}
// If there is something available on the serial read it and write the data
else {
byte in = Serial.read();
in = changeBrightnessByte(in);
byteWriter(in); // Write the incomming byte
byteReceived++;
// If 9600 bytes (number of bytes on screen) is received, wait 1 millisec to set the screen
if(byteReceived == 9600){
digitalWrite(CLOCK, LOW);
delay(1);
byteReceived = 0;
}
}
}
}
/*
* Demo mode function
* This function handels the choosen demo mode and calls the rigth function
*/
void demo() {
// Change mode if demo mode chooser button goes high
if (digitalRead(DEMO_MODE) & ! lastDemoMode) {
lastState = demoState;
demoState = CHANGE_STATE;
}
lastDemoMode = digitalRead(DEMO_MODE);
switch (demoState) {
case BOUNCE_LOGO:
bounceLogo(); // Calls the bounceLogo function
break;
case RANDOM_COLOR:
randomColor(); // Calls the randomColor function
break;
case COLOR_SWIPE:
colorSwipe(); // Calls the colorSwipe function
break;
case FILL_RANDOM:
fillRandom(); // Calls the fillRandom function
break;
case CHANGE_STATE:
switch (lastState) {
case BOUNCE_LOGO:
clearMatrix(); // Calls the clearMatrix function
demoState = RANDOM_COLOR;
break;
case RANDOM_COLOR:
clearMatrix(); // Calls the clearMatrix function
demoState = COLOR_SWIPE;
break;
case COLOR_SWIPE:
initFillRandom = false;
clearMatrix(); // Calls the clearMatrix function
demoState = FILL_RANDOM;
break;
case FILL_RANDOM:
clearMatrix(); // Calls the clearMatrix function
initBounceLogo = false;
speedX = 1;
speedY = 1;
demoState = BOUNCE_LOGO;
break;
}
break;
}
}
/*
* This function takes a byte and breaks it down to bits and write this to the screen
* The function follows the spesific protocol of the WS2812 LEDs
*/
void byteWriter(byte b) {
byte in = changeBrightnessByte(b);
for (byte colorBit = 7; colorBit != 255; colorBit--) {
digitalWrite(CLOCK, LOW);
byte mask = 1 << colorBit;
if (in & mask) {
digitalWrite(DATA, HIGH);
}
else {
digitalWrite(DATA, LOW);
}
digitalWrite(CLOCK, HIGH);
}
}
/*
* This function takes a long and breaks it down to bits and write this to the screen
* The function follows the spesific protocol of the WS2812 LEDs
*/
void longWriter(long l) {
long rgb = changeBrightnessLong(l);
for (byte colorBit = 23; colorBit != 255; colorBit--) {
digitalWrite(CLOCK, LOW);
long mask = 1L << colorBit;
if (rgb & mask) {
digitalWrite(DATA, HIGH);
}
else {
digitalWrite(DATA, LOW);
}
digitalWrite(CLOCK, HIGH);
}
}
/*
* This function sets all the pixels in the matrix to black
*/
void clearMatrix() {
for (int y = 0; y < 40; y++) {
for (int x = 0; x < 80; x++) {
pictureMatrix[x][y] = 0x000000;
}
}
}
/*
* This function allows content of 8*8 size to be placed enywhere on the screen
* It takes in the content, start pos x, start pos y and the size of the content.
*/
void addContent(long content[8][8], int startPosX, int startPosY, int contentSize) {
int xPos = startPosX;
int yPos = startPosY;
if (outOfBound(startPosX, startPosY, contentSize)) {
int xBound = startPosX + contentSize;
int yBound = startPosY + contentSize;
if ((xBound > PICTURE_X) && (yBound > PICTURE_Y)) {
for (int y = 0; yPos < PICTURE_Y; y++) {
for (int x = 0; xPos < PICTURE_X; x++) {
pictureMatrix[xPos + x][yPos + y] = content[x][y];
}
}
}
else if (xBound > PICTURE_X) {
for (int y = 0; y < contentSize; y++) {
for (int x = 0; xPos < PICTURE_X; x++) {
pictureMatrix[xPos + x][yPos + y] = content[x][y];
}
}
}
else if (yBound > PICTURE_Y) {
for (int y = 0; yPos < PICTURE_Y; y++) {
for (int x = 0; x < contentSize; x++) {
pictureMatrix[xPos + x][yPos + y] = content[x][y];
}
}
}
}
else {
for (int y = 0; y < contentSize; y++) {
for (int x = 0; x < contentSize; x++) {
pictureMatrix[xPos + x][yPos + y] = content[x][y];
}
}
}
}
/*
* Check if the content goes out of the picture
* Returns true if it does, false if not
*/
boolean outOfBound(int xPos, int yPos, int contentSize) {
int endPosX = xPos + contentSize;
int endPosY = yPos + contentSize;
if ((endPosX > PICTURE_X) || (endPosY > PICTURE_Y)) {
return true;
}
else {
return false;
}
}
/*
* Transform the picture matrix to an array that fits to the screen
*/
void setPictureArray() {
int pixels = 0;
for (int y = 0; y < 40; y++) {
if ((y % 2) == 0) {
for (int x = 0; x < 80; x++, pixels++) {
pictureArray[pixels] = pictureMatrix[x][y];
}
}
else {
for (int x = 79; x >= 0; x--, pixels++) {
pictureArray[pixels] = pictureMatrix[x][y];
}
}
}
}
/*
* Function to make a logo bounce on the screen
*/
void bounceLogo() {
if(!initBounceLogo){
logoPosX = random(0, 70);
logoPosY = random(0, 30);
initBounceLogo = true;
}
if (updateScreen) {
clearMatrix();
addContent(NTNU, logoPosX, logoPosY, 8);
logoPosX += speedX;
logoPosY += speedY;
if (logoPosX == 72) {
speedX *= -1;
}
else if (logoPosX == 0) {
speedX *= -1;
}
if (logoPosY == 32) {
speedY *= -1;
}
else if (logoPosY == 0) {
speedY *= -1;
}
}
}
/*
* Fonction to create a random color an dirplay it at the screen
*/
void randomColor() {
if (millis() > nextRandomColor) {
nextRandomColor = millis() + 1000;
byte r = random(0, 255);
byte g = random(0, 255);
byte b = random(0, 255);
long rgb = r << 16 | g << 8 | b;
for (int y = 0; y < 40; y++) {
for (int x = 0; x < 80; x++) {
pictureMatrix[x][y] = rgb;
}
}
}
}
/*
* Function to generate a color swipe and roll it over the screen
*/
void colorSwipe() {
if (!initColorSwipe) {
byte rgb[3] = {255, 0, 0};
int pixel = 0;
for (int decColor = 0; decColor < 3; decColor++) {
int incColor = decColor == 2 ? 0 : decColor + 1;
for (int i = 0; i < 255; i++, pixel++) {
swipeColors[pixel] = rgb[0] << 16 | rgb[1] << 8 | rgb[2];
rgb[decColor]--;
rgb[incColor]++;
}
}
initColorSwipe = true;
swipePixel = 0;
}
if (updateScreen) {
int swipe = swipePixel;
for (int x = 0; x < 80; x++, swipe++) {
if (swipe == 765) {
swipe = 0;
}
for (int y = 0; y < 40; y++) {
pictureMatrix[x][y] = swipeColors[swipe];
}
}
swipePixel++;
if(swipePixel > 765){
swipePixel = 0;
}
}
}
/*
* Function to randomly set the LEDs on the screen to a random color
*/
void fillRandom() {
if (updateScreen) {
byte r = random(0, 255);
byte g = random(0, 255);
byte b = random(0, 255);
long rgb = r << 16 | g << 8 | b;
int x = random(0, 80);
int y = random(0, 40);
pictureMatrix[x][y] = rgb;
}
}
/*
* Function to take the picture array and write it to the screen
*/
void writeScreen() {
setPictureArray();
for (int x = 0; x < 3200; x++) {
longWriter(pictureArray[x]);
}
digitalWrite(CLOCK, LOW);
delay(1);
}
/*
* Function to controll the brigthness of the LEDs when long is input
* Using bitshift to adjust brightness
*/
long changeBrightnessLong(long l) {
byte r = l >> 16;
byte g = l >> 8;
byte b = l;
r = r >> brightnessLevel;
g = g >> brightnessLevel;
b = b >> brightnessLevel;
long rgb = r << 16 | g << 8 | b;
return rgb;
}
/*
* Function to controll the brigthness of the LEDs when byte is input
* Using bitshift to adjust brightness
*/
byte changeBrightnessByte(byte b) {
b = b >> brightnessLevel;
return b;
}
/*
* Function to write on the serial port the current mode at a given time
*/
void writeMode(){
if(millis() > modeTime + 1000){
modeTime += 1000;
if(digitalRead(DEMO)){
Serial.println("demo");
}
else{
Serial.println("serial");
}
}
}