Forum: Mikrocontroller und Digitale Elektronik LED_Matrix mit esp32


von Wukasch D. (smd22)


Lesenswert?

Hallo zusammen

Ich möchte eine LED Matrix 8hx32w mit einem Ws2812 Panel per esp32 
betreiben. Es sollen Zeit, Datum, Pixelbilder, Raumtemperatur(BMP280) 
etc. in Laufschrift angezeigt und mit einem Schalter soll zwischen den 
Anzeigemodi hin und her geswitched werden, auch über dabble app. Für 
Zeit und Wetter verwende ich einen ntp server. Eigentlich habe ich den 
Code so weit fertig, nur funktioniert es leider nicht so wie erwartet 
und es kommt nicht viel an der Matrix an, ausser der Smiley:) wäre 
super, wenn mir jemand einen Tipp geben könnte, woran es liegt?

Vielen Dank im Voraus!

Der Code:

// Adafruit_NeoMatrix example for single NeoPixel Shield.
// Scrolls 'Howdy' across the matrix in a portrait (vertical) 
orientation.
#define CUSTOM_SETTINGS
#define INCLUDE_DABBLEINPUTS_MODULE       //choose dabble ble 
sowftware's input module
#include <DabbleESP32.h>                  //dabble headers
unsigned long lasttime = 0;

#include <Adafruit_GFX.h>                 //GFX libraries for matrix
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#include <WiFi.h>                         //wlan libraries
#include <Wire.h>                         //bme bmp sensor needs this
#include <SPI.h>                          //bme bmp sensor needs this
#include <Adafruit_BMP280.h>              //BMP sensor library

// Choose your prefered pixmap            // every h file shows 
different bmp
//#include "heart24.h"
//#include "yellowsmiley24.h"
//#include "bluesmiley24.h"
#include "smileytongue24.h"

#ifdef ESP8266                            //ESP8266 needs it
#define PIN RX
#endif

#define PIN 17                            //matrix data pin

//#define P32BY8X4
#define P16BY16X4

#if defined(P32BY8X4) || defined(P16BY16X4)
#define BM32
#endif
#ifdef BM32
#include "google32.h"                     //google logo bmp header
// Anything with black does not look so good with the naked eye (better 
on pictures)
//#include "linux32.h"                    //linux logo(tux)
#endif

#ifdef P32BY8X4                           //this is not relevant
// Define full matrix width and height.
#define mw 32
#define mh 8
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(mw, mh, PIN,   //matrix 
definition
                            NEO_MATRIX_TOP     + NEO_MATRIX_LEFT +
                            NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
                            NEO_GRB            + NEO_KHZ800);
#elif defined(P16BY16X4)                //this is our matrix
#define mw 32                           //width
#define mh 16                           //height
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 16, PIN,  //matrix 
definition
                            NEO_MATRIX_TOP     + NEO_MATRIX_LEFT +
                            NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
                            NEO_GRB            + NEO_KHZ800);
#else
// Define matrix width and height.
#define mw 16
#define mh 16

Adafruit_NeoMatrix *matrix = new Adafruit_NeoMatrix(mw, mh,
    PIN,
    NEO_MATRIX_TOP     + NEO_MATRIX_RIGHT +
    NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
    NEO_GRB            + NEO_KHZ800 );
#endif


#define BMP_SCK  (27)               //bme bmp screen pin defines
#define BMP_MISO (33)
#define BMP_MOSI (26)
#define BMP_CS   (25)

//Adafruit_BMP280 bmp;              // I2C
//Adafruit_BMP280 bmp(BMP_CS);      // hardware SPI
Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);  // software 
spi

#include "time.h"                   //time headers

const char* ssid     = "SSID";    //wlan
const char* password = "Passwort";   //wlan

const char* ntpServer = "pool.ntp.org";   //ntp server address
const long  gmtOffset_sec = 0;
const int   daylightOffset_sec = 3600;

#ifndef PSTR
#define PSTR // Make Arduino Due happy
#endif
static const uint16_t PROGMEM
// These bitmaps were written for a backend that only supported
// 4 bits per color with Blue/Green/Red ordering while neomatrix
// uses native 565 color mapping as RGB.
// I'm leaving the arrays as is because it's easier to read
// which color is what when separated on a 4bit boundary
// The demo code will modify the arrays at runtime to be compatible
// with the neomatrix color ordering and bit depth.
RGB_bmp[][64] = {
  // 00: blue, blue/red, red, red/green, green, green/blue, blue, white
  { 0x100, 0x200, 0x300, 0x400, 0x600, 0x800, 0xA00, 0xF00,
    0x101, 0x202, 0x303, 0x404, 0x606, 0x808, 0xA0A, 0xF0F,
    0x001, 0x002, 0x003, 0x004, 0x006, 0x008, 0x00A, 0x00F,
    0x011, 0x022, 0x033, 0x044, 0x066, 0x088, 0x0AA, 0x0FF,
    0x010, 0x020, 0x030, 0x040, 0x060, 0x080, 0x0A0, 0x0F0,
    0x110, 0x220, 0x330, 0x440, 0x660, 0x880, 0xAA0, 0xFF0,
    0x100, 0x200, 0x300, 0x400, 0x600, 0x800, 0xA00, 0xF00,
    0x111, 0x222, 0x333, 0x444, 0x666, 0x888, 0xAAA, 0xFFF,
  },

  // 01: grey to white
  { 0x111, 0x222, 0x333, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
    0x222, 0x222, 0x333, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
    0x333, 0x333, 0x333, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
    0x555, 0x555, 0x555, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
    0x777, 0x777, 0x777, 0x777, 0x777, 0x999, 0xAAA, 0xFFF,
    0x999, 0x999, 0x999, 0x999, 0x999, 0x999, 0xAAA, 0xFFF,
    0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xFFF,
    0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF,
  },

  // 02: low red to high red
  { 0x001, 0x002, 0x003, 0x005, 0x007, 0x009, 0x00A, 0x00F,
    0x002, 0x002, 0x003, 0x005, 0x007, 0x009, 0x00A, 0x00F,
    0x003, 0x003, 0x003, 0x005, 0x007, 0x009, 0x00A, 0x00F,
    0x005, 0x005, 0x005, 0x005, 0x007, 0x009, 0x00A, 0x00F,
    0x007, 0x007, 0x007, 0x007, 0x007, 0x009, 0x00A, 0x00F,
    0x009, 0x009, 0x009, 0x009, 0x009, 0x009, 0x00A, 0x00F,
    0x00A, 0x00A, 0x00A, 0x00A, 0x00A, 0x00A, 0x00A, 0x00F,
    0x00F, 0x00F, 0x00F, 0x00F, 0x00F, 0x00F, 0x00F, 0x00F,
  },

  // 03: low green to high green
  { 0x010, 0x020, 0x030, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
    0x020, 0x020, 0x030, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
    0x030, 0x030, 0x030, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
    0x050, 0x050, 0x050, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
    0x070, 0x070, 0x070, 0x070, 0x070, 0x090, 0x0A0, 0x0F0,
    0x090, 0x090, 0x090, 0x090, 0x090, 0x090, 0x0A0, 0x0F0,
    0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0F0,
    0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0,
  },

  // 04: low blue to high blue
  { 0x100, 0x200, 0x300, 0x500, 0x700, 0x900, 0xA00, 0xF00,
    0x200, 0x200, 0x300, 0x500, 0x700, 0x900, 0xA00, 0xF00,
    0x300, 0x300, 0x300, 0x500, 0x700, 0x900, 0xA00, 0xF00,
    0x500, 0x500, 0x500, 0x500, 0x700, 0x900, 0xA00, 0xF00,
    0x700, 0x700, 0x700, 0x700, 0x700, 0x900, 0xA00, 0xF00,
    0x900, 0x900, 0x900, 0x900, 0x900, 0x900, 0xA00, 0xF00,
    0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xF00,
    0xF00, 0xF00, 0xF00, 0xF00, 0xF00, 0xF00, 0xF00, 0xF00,
  },

  // 05: 1 black, 2R, 2O, 2G, 1B with 4 blue lines rising right
  { 0x000, 0x200, 0x000, 0x400, 0x000, 0x800, 0x000, 0xF00,
    0x000, 0x201, 0x002, 0x403, 0x004, 0x805, 0x006, 0xF07,
    0x008, 0x209, 0x00A, 0x40B, 0x00C, 0x80D, 0x00E, 0xF0F,
    0x000, 0x211, 0x022, 0x433, 0x044, 0x855, 0x066, 0xF77,
    0x088, 0x299, 0x0AA, 0x4BB, 0x0CC, 0x8DD, 0x0EE, 0xFFF,
    0x000, 0x210, 0x020, 0x430, 0x040, 0x850, 0x060, 0xF70,
    0x080, 0x290, 0x0A0, 0x4B0, 0x0C0, 0x8D0, 0x0E0, 0xFF0,
    0x000, 0x200, 0x000, 0x500, 0x000, 0x800, 0x000, 0xF00,
  },

  // 06: 4 lines of increasing red and then green
  { 0x000, 0x000, 0x001, 0x001, 0x002, 0x002, 0x003, 0x003,
    0x004, 0x004, 0x005, 0x005, 0x006, 0x006, 0x007, 0x007,
    0x008, 0x008, 0x009, 0x009, 0x00A, 0x00A, 0x00B, 0x00B,
    0x00C, 0x00C, 0x00D, 0x00D, 0x00E, 0x00E, 0x00F, 0x00F,
    0x000, 0x000, 0x010, 0x010, 0x020, 0x020, 0x030, 0x030,
    0x040, 0x040, 0x050, 0x050, 0x060, 0x060, 0x070, 0x070,
    0x080, 0x080, 0x090, 0x090, 0x0A0, 0x0A0, 0x0B0, 0x0B0,
    0x0C0, 0x0C0, 0x0D0, 0x0D0, 0x0E0, 0x0E0, 0x0F0, 0x0F0,
  },

  // 07: 4 lines of increasing red and then blue
  { 0x000, 0x000, 0x001, 0x001, 0x002, 0x002, 0x003, 0x003,
    0x004, 0x004, 0x005, 0x005, 0x006, 0x006, 0x007, 0x007,
    0x008, 0x008, 0x009, 0x009, 0x00A, 0x00A, 0x00B, 0x00B,
    0x00C, 0x00C, 0x00D, 0x00D, 0x00E, 0x00E, 0x00F, 0x00F,
    0x000, 0x000, 0x100, 0x100, 0x200, 0x200, 0x300, 0x300,
    0x400, 0x400, 0x500, 0x500, 0x600, 0x600, 0x700, 0x700,
    0x800, 0x800, 0x900, 0x900, 0xA00, 0xA00, 0xB00, 0xB00,
    0xC00, 0xC00, 0xD00, 0xD00, 0xE00, 0xE00, 0xF00, 0xF00,
  },

  // 08: criss cross of green and red with diagonal blue.
  { 0xF00, 0x001, 0x003, 0x005, 0x007, 0x00A, 0x00F, 0x000,
    0x020, 0xF21, 0x023, 0x025, 0x027, 0x02A, 0x02F, 0x020,
    0x040, 0x041, 0xF43, 0x045, 0x047, 0x04A, 0x04F, 0x040,
    0x060, 0x061, 0x063, 0xF65, 0x067, 0x06A, 0x06F, 0x060,
    0x080, 0x081, 0x083, 0x085, 0xF87, 0x08A, 0x08F, 0x080,
    0x0A0, 0x0A1, 0x0A3, 0x0A5, 0x0A7, 0xFAA, 0x0AF, 0x0A0,
    0x0F0, 0x0F1, 0x0F3, 0x0F5, 0x0F7, 0x0FA, 0xFFF, 0x0F0,
    0x000, 0x001, 0x003, 0x005, 0x007, 0x00A, 0x00F, 0xF00,
  },

  // 09: 2 lines of green, 2 red, 2 orange, 2 green
  { 0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
    0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
    0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
    0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
    0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
    0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
    0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
    0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
  },

  // 10: multicolor smiley face
  { 0x000, 0x000, 0x00F, 0x00F, 0x00F, 0x00F, 0x000, 0x000,
    0x000, 0x00F, 0x000, 0x000, 0x000, 0x000, 0x00F, 0x000,
    0x00F, 0x000, 0xF00, 0x000, 0x000, 0xF00, 0x000, 0x00F,
    0x00F, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00F,
    0x00F, 0x000, 0x0F0, 0x000, 0x000, 0x0F0, 0x000, 0x00F,
    0x00F, 0x000, 0x000, 0x0F4, 0x0F3, 0x000, 0x000, 0x00F,
    0x000, 0x00F, 0x000, 0x000, 0x000, 0x000, 0x00F, 0x000,
    0x000, 0x000, 0x00F, 0x00F, 0x00F, 0x00F, 0x000, 0x000,
  },
};




const uint16_t colors[] = {
  matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 
255)
};


int pixelPerChar = 6;
int maxDisplacement;
int mode = 0;
int brthns = 10;
char page = 0, show_color = 0;

int y = matrix.height();
int x = matrix.width();
int pass = 0;
int line_pass = 0;
char i = 0, j, k ;
char screen[10];
signed int IndexX = 0, IndexY = 2;
typedef enum {
  ToLeft = 0,
  ToRight
} SlipDir_;
SlipDir_ SlipDir = ToLeft;

typedef enum {                      //modus define struct
  DATE = 0,
  CALENDAR,
  ALARM,
  WEATHER,
  TEMPRATURE,
  ALTITUDE,
  PRESSURE,
  ANIMATION

} STATE_;
STATE_ state = DATE;
char str_temp[50] = "TEMP";
int count = 0;
struct tm timeinfo;
float temp, pres, alt;
void setup() {
  pinMode(12, INPUT_PULLUP);                  //pin 12 pullup enable
  attachInterrupt(12, int1, RISING);          //pin 12 interrupt enable
  Serial.begin(115200);                          //serial port enable 
@115200 bps
  Dabble.begin("MyEsp32");                       //bluetooth enabel & 
set bluetooth name of your device
  unsigned status;                                //bmp sensor's 
received status variable
  status = bmp.begin();
  if (!status) {                                //if bmp not recognized
    Serial.println(F("Could not find BMP280"));
    Serial.print(F("SensorID:0x")); Serial.println(bmp.sensorID(), 16);

    while (1) delay(10);
  }

  /* Default settings from datasheet. */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. 
*/
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. 
oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure 
oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

  WiFi.begin(ssid, password);                       //start wifi
  while (WiFi.status() != WL_CONNECTED) {         //until connect delay 
500 ms and push . to uart
    delay(500);
    Serial.print(".");
  }
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);   //get time 
from ntp server
  printLocalTime();                                           //print 
time to uart (disabled)

  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);                                      //close 
wifi if open because we are done with ntp
  WiFi.mode(WIFI_OFF);                                        //mode 
select
  matrix.begin();                                             //enable 
matrix
  matrix.setTextWrap(false);                                  //disable 
text wrap
  matrix.setBrightness(10);
  matrix.setTextColor(colors[0]);                             //first 
text color

  int1();                                                     //run 
interrupt rutine to load status machine

}
unsigned char btn = 0;
void loop() {
  Dabble.processInput();                                      //dabble 
process
  btn = Inputs.getTactileSwitch1Value();                      //get 
phone software button state
  if (btn == 1) {                                             //if 
pressed run interrupt routine
    int1();
    delay(50);                                                //software 
debounce delay

  }
  brthns = Inputs.getPot1Value() >> 2;                        // get 
rotary pot value from phone
  if (brthns < 1) brthns = 5;                                 // set 
brigthnes, but if brghnts lower than 1, set 5, because if 0 there is no 
display
  matrix.setBrightness(brthns * 2);                           // 
brightness can be set 0-255, we get from 0-100 from phone, normally we 
multiple with 2.55 to convert, but 2 is enough

  if (state == ANIMATION) {                                   //check 
state machine,

#ifdef BM32
    if (state == ANIMATION) display_panOrBounceBitmap(32);    //show 
first bmp animation (google logo or linux logo)
#endif
    // pan a big pixmap
    if (state == ANIMATION) display_panOrBounceBitmap(24);    //shoe bmp 
second animation
    // bounce around a small one
    if (state == ANIMATION) display_panOrBounceBitmap(8);     //show 
last animation
    int1();                                                   //run 
interrupt routine and take the state machine next position
  } else {                                                     //if 
state is not ANIMATION
    matrix.clear();                                           //clear 
matric
    matrix.fillScreen(0);                                     //clear 
colors
    matrix.setCursor(x, 2);                                   //set 
cursor to y 2
    matrix.print(str_temp);                                   //str_temp 
loading in int1() routine,

    if (--x < -100) {                                         //this is 
shifting routine, when x reaches to -100, take back to 0
      if (++pass >= 3) pass = 0;
      matrix.setTextColor(colors[pass]);
    }
    matrix.show();                                            //show 
matrix
  }


  if (count++ > 49 ) {                                          //every 
50 loop, print sensor values to uart, its for debugging
    temp = bmp.readTemperature();
    pres = bmp.readPressure();
    alt = bmp.readAltitude(1013.25);

    Serial.print(F("Temperature = "));
    Serial.print(temp);
    Serial.println(F(" *C"));

    Serial.print(F("Pressure = "));
    Serial.print(pres);
    Serial.println(F(" Pa"));

    Serial.print(F("Approx altitude = "));
    Serial.print(alt);
    Serial.println(F(" m"));

    Serial.print(F("Brightness = "));
    Serial.print(brthns);

    Serial.print(F("Button = "));
    Serial.print(btn);
    Serial.println();

    printLocalTime();
    count = 0;



  }


  delay(75); 
//shifting time
}

void printLocalTime() {                                         //print 
time information to uart, disabled

  if (!getLocalTime(&timeinfo)) {
    Serial.println(F("Failed"));
    return;
  }
  /*  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
    Serial.print("Day of week: ");
    Serial.println(&timeinfo, "%A");
    Serial.print("Month: ");
    Serial.println(&timeinfo, "%B");
    Serial.print("Day of Month: ");
    Serial.println(&timeinfo, "%d");
    Serial.print("Year: ");
    Serial.println(&timeinfo, "%Y");
    Serial.print("Hour: ");
    Serial.println(&timeinfo, "%H");
    Serial.print("Hour (12 hour format): ");
    Serial.println(&timeinfo, "%I");
    Serial.print("Minute: ");
    Serial.println(&timeinfo, "%M");
    Serial.print("Second: ");
    Serial.println(&timeinfo, "%S");

    Serial.println("Time variables");
    char timeHour[3];
    strftime(timeHour,3, "%H", &timeinfo);
    Serial.println(timeHour);
    char timeWeekDay[10];
    strftime(timeWeekDay,10, "%A", &timeinfo);
    Serial.println(timeWeekDay);
    Serial.println();*/
}
void int1(void) { 
//interrupt routine, runs every tact pushed, and every phone button 
pushed
  //delay(200);
  IndexX = 0;
  switch (state) {
    case DATE:
      strftime(str_temp, sizeof(str_temp), "DATE:%d.%m.%Y %H:%M", 
&timeinfo); //load str_temp with date information,
      state = TEMPRATURE; 
//go to n ext state
      break;
    /*
      case CALENDAR:

      state = ALARM;
      break;
      case ALARM:
      strftime(str_temp,sizeof(str_temp),"TIME:%H.%M",&timeinfo);
      state = WEATHER;
      break;
      case WEATHER:
      state = TEMPRATURE;
      break;*/

    case TEMPRATURE: 
//load str with temprature information, 02.1f --> even if temp is 5 
degree, it prints 05.0
      sprintf(str_temp, "TEMP:%02.1f", temp);
      state = ALTITUDE;
      break;
    case ALTITUDE:
      sprintf(str_temp, "ALTITUDE:%02.02f", alt); 
//load str with altitude information, 02.1f --> even if temp is 5 
degree, it prints 05.0
      state = PRESSURE;
      break;
    case PRESSURE:
      sprintf(str_temp, "PRESSURE:%02.1f", pres);
      state = ANIMATION;
      break;
    case ANIMATION:
      strftime(str_temp, sizeof(str_temp), "DATE:%d.%m.%Y %H:%M", 
&timeinfo);
      state = DATE;
      break;

    default: break;
  }
  Serial.print(F("State = ")); 
//print state to uart, for debugging
  Serial.println(state);
}

void display_panOrBounceBitmap (uint8_t bitmapSize) { 
//This is ready library from examples, not written by me
  // keep integer math, deal with values 16 times too big
  // start by showing upper left of big bitmap or centering if the 
display is big
  int16_t xf = max(0, (mw - bitmapSize) / 2) << 4;
  int16_t yf = max(0, (mh - bitmapSize) / 2) << 4;
  // scroll speed in 1/16th
  int16_t xfc = 6;
  int16_t yfc = 3;
  // scroll down and right by moving upper left corner off screen
  // more up and left (which means negative numbers)
  int16_t xfdir = -1;
  int16_t yfdir = -1;

  for (uint16_t i = 1; i < 200; i++) {
    bool updDir = false;

    // Get actual x/y by dividing by 16.
    int16_t x = xf >> 4;
    int16_t y = yf >> 4;

    matrix.clear();
    // bounce 8x8 tri color smiley face around the screen
    if (bitmapSize == 8) fixdrawRGBBitmap(x, y, RGB_bmp[10], 8, 8);
    // pan 24x24 pixmap
    if (bitmapSize == 24) matrix.drawRGBBitmap(x, y, (const uint16_t *) 
bitmap24, bitmapSize, bitmapSize);
#ifdef BM32
    if (bitmapSize == 32) matrix.drawRGBBitmap(x, y, (const uint16_t *) 
bitmap32, bitmapSize, bitmapSize);
#endif
    matrix.show();

    // Only pan if the display size is smaller than the pixmap
    // but not if the difference is too small or it'll look bad.
    if (bitmapSize - mw > 2) {
      xf += xfc * xfdir;
      if (xf >= 0)                      {
        xfdir = -1;
        updDir = true ;
      };
      // we don't go negative past right corner, go back positive
      if (xf <= ((mw - bitmapSize) << 4)) {
        xfdir = 1;
        updDir = true ;
      };
    }
    if (bitmapSize - mh > 2) {
      yf += yfc * yfdir;
      // we shouldn't display past left corner, reverse direction.
      if (yf >= 0)                      {
        yfdir = -1;
        updDir = true ;
      };
      if (yf <= ((mh - bitmapSize) << 4)) {
        yfdir = 1;
        updDir = true ;
      };
    }
    // only bounce a pixmap if it's smaller than the display size
    if (mw > bitmapSize) {
      xf += xfc * xfdir;
      // Deal with bouncing off the 'walls'
      if (xf >= (mw - bitmapSize) << 4) {
        xfdir = -1;
        updDir = true ;
      };
      if (xf <= 0)           {
        xfdir =  1;
        updDir = true ;
      };
    }
    if (mh > bitmapSize) {
      yf += yfc * yfdir;
      if (yf >= (mh - bitmapSize) << 4) {
        yfdir = -1;
        updDir = true ;
      };
      if (yf <= 0)           {
        yfdir =  1;
        updDir = true ;
      };
    }

    if (updDir) {
      // Add -1, 0 or 1 but bind result to 1 to 1.
      // Let's take 3 is a minimum speed, otherwise it's too slow.
      xfc = constrain(xfc + random(-1, 2), 3, 16);
      yfc = constrain(xfc + random(-1, 2), 3, 16);
    }
    delay(10);
  }
}
void fixdrawRGBBitmap(int16_t x, int16_t y, const uint16_t *bitmap, 
int16_t w, int16_t h) {     //This is ready library from examples, not 
written by me
  // work around "a15 cannot be used in asm here" compiler bug when 
using an array on ESP8266
  // uint16_t RGB_bmp_fixed[w * h];
  static uint16_t *RGB_bmp_fixed = (uint16_t *) malloc( w  h  2);
  for (uint16_t pixel = 0; pixel < w * h; pixel++) {
    uint8_t r, g, b;
    uint16_t color = pgm_read_word(bitmap + pixel);

    //Serial.print(color, HEX);
    b = (color & 0xF00) >> 8;
    g = (color & 0x0F0) >> 4;
    r = color & 0x00F;
    //Serial.print(" ");
    //Serial.print(b);
    //Serial.print("/");
    //Serial.print(g);
    //Serial.print("/");
    //Serial.print(r);
    //Serial.print(" -> ");
    // expand from 4/4/4 bits per color to 5/6/5
    b = map(b, 0, 15, 0, 31);
    g = map(g, 0, 15, 0, 63);
    r = map(r, 0, 15, 0, 31);
    //Serial.print(r);
    //Serial.print("/");
    //Serial.print(g);
    //Serial.print("/");
    //Serial.print(b);
    RGB_bmp_fixed[pixel] = (r << 11) + (g << 5) + b;
    //Serial.print(" -> ");
    //Serial.println(RGB_bmp_fixed[pixel], HEX);
  }
  matrix.drawRGBBitmap(x, y, RGB_bmp_fixed, w, h);
}

: Bearbeitet durch User
von Markus M. (adrock)


Lesenswert?

Du solltest Deinen Code nochmal neu strukturieren. Das ist kompletter 
"copy & paste" Spaghetticode.

Die globalen (wenn es denn sein muss) Variablendefinitionen gehören alle 
an Anfang (hinter die #define Sektion). Auch die Funktionsdeklarationen.

Normalerweise sollte es so sein:

- Includes
- Defines
- Funktionsdeklarationen
- Globale Variablen
- Main (Code)
- Funktionen (Code)

Davon abgesehen, soll es nun 32x16 oder 32x8 sein? In Deinem Code hast 
Du jedenfalls 32x16 definiert:
1
#elif defined(P16BY16X4)                //this is our matrix
2
#define mw 32                           //width
3
#define mh 16                           //height
4
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 16, PIN,   //matrix

Mit #define definierte Konstanten schreibt man normalweise per 
Konvention GROSS.

: Bearbeitet durch User
von Martin (Gast)


Lesenswert?

Setz den Code mal in Tags, dann kann man den auch direkt lesen.

von J. S. (jojos)


Lesenswert?

Martin schrieb:
> Setz den Code mal in Tags, dann kann man den auch direkt lesen.

Nein, als Anhang hochladen wie es fett gedruckt im Hinweis steht.
Wollte helfen, habe mir beim scrollen aber den Finger verstaucht.

von Wukasch D. (smd22)


Lesenswert?

Hallo

Habe es etwas entrümpelt, hoffe es ist nun besser lesbar.

1
#define CUSTOM_SETTINGS
2
#define INCLUDE_DABBLEINPUTS_MODULE       //choose dabble ble sowftware's input module
3
#include <DabbleESP32.h>                  //dabble headers
4
unsigned long lasttime = 0;
5
6
#include <Adafruit_GFX.h>                 //GFX libraries for matrix
7
#include <Adafruit_NeoMatrix.h>
8
#include <Adafruit_NeoPixel.h>
9
10
#include <WiFi.h>                         //wlan libraries
11
#include <Wire.h>                         //bme bmp sensor needs this
12
#include <SPI.h>                          //bme bmp sensor needs this
13
#include <Adafruit_BMP280.h>              //BMP sensor library
14
15
#include "smileytongue24.h"
16
17
#ifdef ESP8266                            //ESP8266 needs it
18
#define PIN RX
19
#endif
20
21
#include "headers.h" 
22
23
#define PIN 17                            //matrix data pin
24
#include "google32.h"                     //google logo bmp header 
25
26
#define MW 32
27
#define MH 8
28
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(MW, MH, PIN,   //matrix definition
29
                            NEO_MATRIX_TOP     + NEO_MATRIX_LEFT +
30
                            NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
31
                            NEO_GRB            + NEO_KHZ800);
32
33
#define BMP_SCK  (27)               //bme bmp screen pin defines
34
#define BMP_MISO (33)
35
#define BMP_MOSI (26)
36
#define BMP_CS   (25)
37
38
Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);  // software spi
39
40
#include "time.h"                   //time headers
41
42
const char* ssid     = "SSID";    //wlan
43
const char* password = "PASSWORT";   //wlan
44
45
const char* ntpServer = "pool.ntp.org";   //ntp server address
46
const long  gmtOffset_sec = 0;
47
const int   daylightOffset_sec = 3600;
48
49
const uint16_t colors[] = {
50
  matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 255)
51
};
52
53
int pixelPerChar = 6;
54
int maxDisplacement;
55
int mode = 0;
56
int brthns = 10;
57
char page = 0, show_color = 0;
58
59
int y = matrix.height();
60
int x = matrix.width();
61
int pass = 0;
62
int line_pass = 0;
63
char i = 0, j, k ;
64
char screen[10];
65
signed int IndexX = 0, IndexY = 2;
66
typedef enum {
67
  ToLeft = 0,
68
  ToRight
69
} SlipDir_;
70
SlipDir_ SlipDir = ToLeft;
71
72
typedef enum {                      //modus define struct
73
  DATE = 0,
74
  CALENDAR,
75
  ALARM,
76
  WEATHER,
77
  TEMPRATURE,
78
  ALTITUDE,
79
  PRESSURE,
80
  ANIMATION
81
82
} STATE_;
83
STATE_ state = DATE;
84
char str_temp[50] = "TEMP";
85
int count = 0;
86
struct tm timeinfo;
87
float temp, pres, alt;
88
void setup() {
89
  pinMode(12, INPUT_PULLUP);                  //pin 12 pullup enable
90
  attachInterrupt(12, int1, RISING);          //pin 12 interrupt enable
91
  Serial.begin(115200);                          //serial port enable @115200 bps
92
  Dabble.begin("MyEsp32");                       //bluetooth enabel & set bluetooth name of your device
93
  unsigned status;                                //bmp sensor's received status variable
94
  status = bmp.begin();
95
  if (!status) {                                //if bmp not recognized
96
    Serial.println(F("Could not find BMP280"));
97
    Serial.print(F("SensorID:0x")); Serial.println(bmp.sensorID(), 16);
98
99
    while (1) delay(10);
100
  }
101
102
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
103
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
104
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
105
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
106
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
107
108
  WiFi.begin(ssid, password);                       //start wifi
109
  while (WiFi.status() != WL_CONNECTED) {         //until connect delay 500 ms and push . to uart
110
    delay(500);
111
    Serial.print(".");
112
  }
113
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);   //get time from ntp server
114
  printLocalTime();                                           //print time to uart (disabled)
115
116
  //disconnect WiFi as it's no longer needed
117
  WiFi.disconnect(true);                                      //close wifi if open because we are done with ntp
118
  WiFi.mode(WIFI_OFF);                                        //mode select
119
  matrix.begin();                                             //enable matrix
120
  matrix.setTextWrap(false);                                  //disable text wrap
121
  matrix.setBrightness(10);
122
  matrix.setTextColor(colors[0]);                             //first text color
123
124
  int1();                                                     //run interrupt rutine to load status machine
125
126
}
127
unsigned char btn = 0;
128
void loop() {
129
  Dabble.processInput();                                      //dabble process
130
  btn = Inputs.getTactileSwitch1Value();                      //get phone software button state
131
  if (btn == 1) {                                             //if pressed run interrupt routine
132
    int1();
133
    delay(50);                                                //software debounce delay
134
135
  }
136
  brthns = Inputs.getPot1Value() >> 2;                        // get rotary pot value from phone
137
  if (brthns < 1) brthns = 5;                                 // set brigthnes, but if brghnts lower than 1, set 5, because if 0 there is no display
138
  matrix.setBrightness(brthns * 2);                           // brightness can be set 0-255, we get from 0-100 from phone, normally we multiple with 2.55 to convert, but 2 is enough
139
140
  if (state == ANIMATION) {                                   //check state machine,
141
142
    // pan a big pixmap
143
    if (state == ANIMATION) display_panOrBounceBitmap(24);    //shoe bmp second animation
144
    // bounce around a small one
145
    if (state == ANIMATION) display_panOrBounceBitmap(8);     //show last animation
146
    int1();                                                   //run interrupt routine and take the state machine next position
147
  } else {                                                     //if state is not ANIMATION
148
    matrix.clear();                                           //clear matric
149
    matrix.fillScreen(0);                                     //clear colors
150
    matrix.setCursor(x, 2);                                   //set cursor to y 2
151
    matrix.print(str_temp);                                   //str_temp loading in int1() routine,
152
153
    if (--x < -100) {                                         //this is shifting routine, when x reaches to -100, take back to 0
154
      if (++pass >= 3) pass = 0;
155
      matrix.setTextColor(colors[pass]);
156
    }
157
    matrix.show();                                            //show matrix
158
  }
159
  if (count++ > 49 ) {                                          //every 50 loop, print sensor values to uart, its for debugging
160
    temp = bmp.readTemperature();
161
    pres = bmp.readPressure();
162
    alt = bmp.readAltitude(1013.25);
163
164
    Serial.print(F("Temperature = "));
165
    Serial.print(temp);
166
    Serial.println(F(" *C"));
167
168
    Serial.print(F("Pressure = "));
169
    Serial.print(pres);
170
    Serial.println(F(" Pa"));
171
172
    Serial.print(F("Approx altitude = "));
173
    Serial.print(alt);
174
    Serial.println(F(" m"));
175
176
    Serial.print(F("Brightness = "));
177
    Serial.print(brthns);
178
179
    Serial.print(F("Button = "));
180
    Serial.print(btn);
181
    Serial.println();
182
183
    printLocalTime();
184
    count = 0;
185
  }
186
  delay(75);                                                    //shifting time
187
}
188
189
void printLocalTime() {                                         //print time information to uart, disabled
190
191
  if (!getLocalTime(&timeinfo)) {
192
    Serial.println(F("Failed"));
193
    return;
194
  }
195
}
196
void int1(void) {                                                           //interrupt routine, runs every tact pushed, and every phone button pushed
197
  //delay(200);
198
  IndexX = 0;
199
  switch (state) {
200
    case DATE:
201
      strftime(str_temp, sizeof(str_temp), "DATE:%d.%m.%Y %H:%M", &timeinfo); //load str_temp with date information,
202
      state = TEMPRATURE;                                                   //go to n ext state
203
      break;
204
    case TEMPRATURE:                                                        //load str with temprature information, 02.1f --> even if temp is 5 degree, it prints 05.0
205
      sprintf(str_temp, "TEMP:%02.1f", temp);
206
      state = ALTITUDE;
207
      break;
208
    case ALTITUDE:
209
      sprintf(str_temp, "ALTITUDE:%02.02f", alt);                           //load str with altitude information, 02.1f --> even if temp is 5 degree, it prints 05.0
210
      state = PRESSURE;
211
      break;
212
    case PRESSURE:
213
      sprintf(str_temp, "PRESSURE:%02.1f", pres);
214
      state = ANIMATION;
215
      break;
216
    case ANIMATION:
217
      strftime(str_temp, sizeof(str_temp), "DATE:%d.%m.%Y %H:%M", &timeinfo);
218
      state = DATE;
219
      break;
220
    default: break;
221
  }
222
  Serial.print(F("State = "));                                                //print state to uart, for debugging
223
  Serial.println(state);
224
}
225
226
void display_panOrBounceBitmap (uint8_t bitmapSize) {                       //This is ready library from examples, not written by me
227
  // keep integer math, deal with values 16 times too big
228
  // start by showing upper left of big bitmap or centering if the display is big
229
  int16_t xf = max(0, (MW - bitmapSize) / 2) << 4;
230
  int16_t yf = max(0, (MH - bitmapSize) / 2) << 4;
231
  // scroll speed in 1/16th
232
  int16_t xfc = 6;
233
  int16_t yfc = 3;
234
  // scroll down and right by moving upper left corner off screen
235
  // more up and left (which means negative numbers)
236
  int16_t xfdir = -1;
237
  int16_t yfdir = -1;
238
239
  for (uint16_t i = 1; i < 200; i++) {
240
    bool updDir = false;
241
242
    // Get actual x/y by dividing by 16.
243
    int16_t x = xf >> 4;
244
    int16_t y = yf >> 4;
245
246
    matrix.clear();
247
    // bounce 8x8 tri color smiley face around the screen
248
    if (bitmapSize == 8) fixdrawRGBBitmap(x, y, RGB_bmp[10], 8, 8);
249
    // pan 24x24 pixmap
250
    if (bitmapSize == 24) matrix.drawRGBBitmap(x, y, (const uint16_t *) bitmap24, bitmapSize, bitmapSize);
251
    if (bitmapSize == 32) matrix.drawRGBBitmap(x, y, (const uint16_t *) bitmap32, bitmapSize, bitmapSize);
252
    matrix.show();
253
254
    // Only pan if the display size is smaller than the pixmap
255
    // but not if the difference is too small or it'll look bad.
256
    if (bitmapSize - MW  > 2) {
257
      xf += xfc * xfdir;
258
      if (xf >= 0)                      {
259
        xfdir = -1;
260
        updDir = true ;
261
      };
262
      // we don't go negative past right corner, go back positive
263
      if (xf <= ((MW - bitmapSize) << 4)) {
264
        xfdir = 1;
265
        updDir = true ;
266
      };
267
    }
268
    if (bitmapSize - MH > 2) {
269
      yf += yfc * yfdir;
270
      // we shouldn't display past left corner, reverse direction.
271
      if (yf >= 0)                      {
272
        yfdir = -1;
273
        updDir = true ;
274
      };
275
      if (yf <= ((MH - bitmapSize) << 4)) {
276
        yfdir = 1;
277
        updDir = true ;
278
      };
279
    }
280
    // only bounce a pixmap if it's smaller than the display size
281
    if (MW > bitmapSize) {
282
      xf += xfc * xfdir;
283
      // Deal with bouncing off the 'walls'
284
      if (xf >= (MW - bitmapSize) << 4) {
285
        xfdir = -1;
286
        updDir = true ;
287
      };
288
      if (xf <= 0)           {
289
        xfdir =  1;
290
        updDir = true ;
291
      };
292
    }
293
    if (MH > bitmapSize) {
294
      yf += yfc * yfdir;
295
      if (yf >= (MH - bitmapSize) << 4) {
296
        yfdir = -1;
297
        updDir = true ;
298
      };
299
      if (yf <= 0)           {
300
        yfdir =  1;
301
        updDir = true ;
302
      };
303
    }
304
305
    if (updDir) {
306
      // Add -1, 0 or 1 but bind result to 1 to 1.
307
      // Let's take 3 is a minimum speed, otherwise it's too slow.
308
      xfc = constrain(xfc + random(-1, 2), 3, 16);
309
      yfc = constrain(xfc + random(-1, 2), 3, 16);
310
    }
311
    delay(10);
312
  }
313
}
314
void fixdrawRGBBitmap(int16_t x, int16_t y, const uint16_t *bitmap, int16_t w, int16_t h) {     
315
  
316
  //This is ready library from examples, not written by me
317
  // work around "a15 cannot be used in asm here" compiler bug when using an array on ESP8266
318
  // uint16_t RGB_bmp_fixed[w * h];
319
  static uint16_t *RGB_bmp_fixed = (uint16_t *) malloc( w * h * 2);
320
  for (uint16_t pixel = 0; pixel < w * h; pixel++) {
321
    uint8_t r, g, b;
322
    uint16_t color = pgm_read_word(bitmap + pixel);
323
    //Serial.print(color, HEX);
324
    b = (color & 0xF00) >> 8;
325
    g = (color & 0x0F0) >> 4;
326
    r = color & 0x00F;
327
    // expand from 4/4/4 bits per color to 5/6/5
328
    b = map(b, 0, 15, 0, 31);
329
    g = map(g, 0, 15, 0, 63);
330
    r = map(r, 0, 15, 0, 31);
331
    RGB_bmp_fixed[pixel] = (r << 11) + (g << 5) + b;
332
  }
333
  matrix.drawRGBBitmap(x, y, RGB_bmp_fixed, w, h);
334
}

von Joachim B. (jar)


Lesenswert?

lieber TO was hast du an

J. S. schrieb:
> Nein, als Anhang hochladen wie es fett gedruckt im Hinweis steht.
> Wollte helfen, habe mir beim scrollen aber den Finger verstaucht.

nicht verstanden?

Wukasch D. schrieb:
> Habe es etwas entrümpelt, hoffe es ist nun besser lesbar.

das ist kein bisschen besser!

von Martin (Gast)


Lesenswert?

So habe ich auch keine Lust zu helfen.

von Tom (Gast)


Lesenswert?

Mir auch unverständlich warum man nicht lesen kann bevor man postet. Das 
ist sehr unübersichtlich so und werde ich ebenfalls nicht lesen
..und dann das gleich ein zweites Mal drunter zu posten..da fällt einem 
nichts mehr ein

von Ralf G. (ralg)


Lesenswert?

Wukasch D. schrieb:
> Eigentlich habe ich den
> Code so weit fertig, nur funktioniert es leider nicht so wie erwartet
> und es kommt nicht viel an der Matrix an, ausser der Smiley:) wäre
> super, wenn mir jemand einen Tipp geben könnte, woran es liegt?

Da wirst du wohl was falsch gemacht haben...

Herangehensweise:
1. Verstehen, was man da zusammenkopiert hat!
2. Alles rausschmeißen, was nicht zur Darstellung einer Bitmap gehört
3. Vergleiche mal die Arraygrößen, -anordnungen und sonstige 
'Eigenheiten' in der "smileytongue24.h" mit deinen gebastelten Bitmaps.
4. Falls nichts direkt ins Auge springt, erstmal Bitmaps mit einfarbigen 
Flächen, danach mit Streifen erstellen. Da kann man wahrscheinlich schon 
ein 'System' erkennen und danach den Fehler beheben.

von mIstA (Gast)


Lesenswert?

Wukasch D. schrieb:
> es kommt nicht viel an der Matrix an, ausser der Smiley:)

Und was kommt an der seriellen Schnittstelle an Debug-Info an?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.