diff --git a/matrix/imageScreen/ModuleAir128x64.png b/matrix/imageScreen/ModuleAir128x64.png new file mode 100644 index 0000000..e9ee55f Binary files /dev/null and b/matrix/imageScreen/ModuleAir128x64.png differ diff --git a/matrix/imageScreen/planet1.png b/matrix/imageScreen/planet1.png new file mode 100644 index 0000000..4cca7f1 Binary files /dev/null and b/matrix/imageScreen/planet1.png differ diff --git a/matrix/test_forms_infinite b/matrix/imageScreen/test_image similarity index 61% rename from matrix/test_forms_infinite rename to matrix/imageScreen/test_image index f8154cc..486356f 100644 Binary files a/matrix/test_forms_infinite and b/matrix/imageScreen/test_image differ diff --git a/matrix/imageScreen/test_image.cc b/matrix/imageScreen/test_image.cc new file mode 100644 index 0000000..8b23e93 --- /dev/null +++ b/matrix/imageScreen/test_image.cc @@ -0,0 +1,194 @@ +// -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- +// +// Example how to display an image, including animated images using +// ImageMagick. For a full utility that does a few more things, have a look +// at the led-image-viewer in ../utils +// +// Showing an image is not so complicated, essentially just copy all the +// pixels to the canvas. How to get the pixels ? In this example we're using +// the graphicsmagick library as universal image loader library that +// can also deal with animated images. +// You can of course do your own image loading or use some other library. +// +// This requires an external dependency, so install these first before you +// can call `make image-example` +// sudo apt-get update +// sudo apt-get install libgraphicsmagick++-dev libwebp-dev -y +// make image-example + +/* +pour compiler: +g++ -I/var/www/moduleair_pro_4g/matrix/include -L/var/www/moduleair_pro_4g/matrix/lib /var/www/moduleair_pro_4g/matrix/imageScreen/test_image.cc -o /var/www/moduleair_pro_4g/matrix/imageScreen/test_image -lrgbmatrix +g++ -I/var/www/moduleair_pro_4g/matrix/include -L/var/www/moduleair_pro_4g/matrix/lib /var/www/moduleair_pro_4g/matrix/imageScreen/test_image.cc -o /var/www/moduleair_pro_4g/matrix/imageScreen/test_image -lrgbmatrix `GraphicsMagick++-config --cppflags --libs` + +pour lancer: +sudo /var/www/moduleair_pro_4g/matrix/imageScreen/test_image /var/www/moduleair_pro_4g/matrix/imageScreen/ModuleAir128x64.png + +*/ + +#include "led-matrix.h" + +#include +#include +#include +#include + +#include +#include +#include + +using rgb_matrix::Canvas; +using rgb_matrix::RGBMatrix; +using rgb_matrix::FrameCanvas; + +// Make sure we can exit gracefully when Ctrl-C is pressed. +volatile bool interrupt_received = false; +static void InterruptHandler(int signo) { + interrupt_received = true; +} + +using ImageVector = std::vector; + +// Given the filename, load the image and scale to the size of the +// matrix. +// // If this is an animated image, the resutlting vector will contain multiple. +static ImageVector LoadImageAndScaleImage(const char *filename, + int target_width, + int target_height) { + ImageVector result; + + ImageVector frames; + try { + readImages(&frames, filename); + } catch (std::exception &e) { + if (e.what()) + fprintf(stderr, "%s\n", e.what()); + return result; + } + + if (frames.empty()) { + fprintf(stderr, "No image found."); + return result; + } + + // Animated images have partial frames that need to be put together + if (frames.size() > 1) { + Magick::coalesceImages(&result, frames.begin(), frames.end()); + } else { + result.push_back(frames[0]); // just a single still image. + } + + for (Magick::Image &image : result) { + image.scale(Magick::Geometry(target_width, target_height)); + } + + return result; +} + + +// Copy an image to a Canvas. Note, the RGBMatrix is implementing the Canvas +// interface as well as the FrameCanvas we use in the double-buffering of the +// animted image. +void CopyImageToCanvas(const Magick::Image &image, Canvas *canvas) { + const int offset_x = 0, offset_y = 0; // If you want to move the image. + // Copy all the pixels to the canvas. + for (size_t y = 0; y < image.rows(); ++y) { + for (size_t x = 0; x < image.columns(); ++x) { + const Magick::Color &c = image.pixelColor(x, y); + if (c.alphaQuantum() < 256) { + canvas->SetPixel(x + offset_x, y + offset_y, + ScaleQuantumToChar(c.redQuantum()), + ScaleQuantumToChar(c.greenQuantum()), + ScaleQuantumToChar(c.blueQuantum())); + } + } + } +} + +// An animated image has to constantly swap to the next frame. +// We're using double-buffering and fill an offscreen buffer first, then show. +void ShowAnimatedImage(const ImageVector &images, RGBMatrix *matrix) { + FrameCanvas *offscreen_canvas = matrix->CreateFrameCanvas(); + while (!interrupt_received) { + for (const auto &image : images) { + if (interrupt_received) break; + CopyImageToCanvas(image, offscreen_canvas); + offscreen_canvas = matrix->SwapOnVSync(offscreen_canvas); + usleep(image.animationDelay() * 10000); // 1/100s converted to usec + } + } +} + +int usage(const char *progname) { + fprintf(stderr, "Usage: %s [led-matrix-options] \n", + progname); + rgb_matrix::PrintMatrixFlags(stderr); + return 1; +} + +int main(int argc, char *argv[]) { + Magick::InitializeMagick(*argv); + + // Check if a filename was provided + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + const char *filename = argv[1]; + + // Initialize with hardcoded defaults for your specific hardware + RGBMatrix::Options defaults; + defaults.hardware_mapping = "moduleair_pinout"; + defaults.rows = 64; + defaults.cols = 128; + defaults.chain_length = 1; + defaults.parallel = 1; + defaults.row_address_type = 3; + defaults.show_refresh_rate = true; + defaults.brightness = 100; + defaults.pwm_bits = 1; + defaults.panel_type = "FM6126A"; + defaults.disable_hardware_pulsing = false; + + // Set up runtime options (still needed) + rgb_matrix::RuntimeOptions runtime_opt; + runtime_opt.gpio_slowdown = 4; // Adjust if needed for your Pi model + runtime_opt.daemon = 0; + runtime_opt.drop_privileges = 0; // Set to 1 if not running as root + + // Handle Ctrl+C to exit gracefully + signal(SIGTERM, InterruptHandler); + signal(SIGINT, InterruptHandler); + + // Create the matrix with our defaults + RGBMatrix *matrix = RGBMatrix::CreateFromOptions(defaults, runtime_opt); + if (matrix == NULL) { + fprintf(stderr, "Failed to create matrix\n"); + return 1; + } + + // Load and process the image + ImageVector images = LoadImageAndScaleImage(filename, + matrix->width(), + matrix->height()); + + // Display the image(s) + switch (images.size()) { + case 0: // failed to load image + fprintf(stderr, "Failed to load image\n"); + break; + case 1: // single image to show + CopyImageToCanvas(images[0], matrix); + while (!interrupt_received) sleep(1); // Until Ctrl-C is pressed + break; + default: // animation with multiple frames + ShowAnimatedImage(images, matrix); + break; + } + + // Clean up + matrix->Clear(); + delete matrix; + + return 0; +} \ No newline at end of file diff --git a/matrix/screen_sensors b/matrix/screenSensors/screen_sensors old mode 100755 new mode 100644 similarity index 100% rename from matrix/screen_sensors rename to matrix/screenSensors/screen_sensors diff --git a/matrix/screen_sensors.cc b/matrix/screenSensors/screen_sensors.cc old mode 100755 new mode 100644 similarity index 100% rename from matrix/screen_sensors.cc rename to matrix/screenSensors/screen_sensors.cc diff --git a/matrix/screen_sensors_loop b/matrix/screenSensors/screen_sensors_loop old mode 100755 new mode 100644 similarity index 100% rename from matrix/screen_sensors_loop rename to matrix/screenSensors/screen_sensors_loop diff --git a/matrix/screen_sensors_loop.cc b/matrix/screenSensors/screen_sensors_loop.cc old mode 100755 new mode 100644 similarity index 100% rename from matrix/screen_sensors_loop.cc rename to matrix/screenSensors/screen_sensors_loop.cc diff --git a/matrix/test_forms b/matrix/test_forms deleted file mode 100755 index 9295ddd..0000000 Binary files a/matrix/test_forms and /dev/null differ diff --git a/matrix/test_forms.cc b/matrix/test_forms.cc deleted file mode 100755 index 6ee7576..0000000 --- a/matrix/test_forms.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* - - __ __ _ _____ ____ _____ __ - | \/ | / \|_ _| _ \|_ _\ \/ / - | |\/| | / _ \ | | | |_) || | \ / - | | | |/ ___ \| | | _ < | | / \ - |_| |_/_/ \_\_| |_| \_\___/_/\_\ - - -Script to display a simple square on the matrix LED -sudo /var/www/moduleair_pro_4g/matrix/test_forms --led-no-hardware-pulse - -Pour compiler: -g++ -Iinclude -Llib test_forms.cc -o test_forms -lrgbmatrix - -Pour le lancer: -sudo /var/www/moduleair_pro_4g/matrix/test_forms -*/ - -#include "led-matrix.h" -#include "graphics.h" - -#include - -using rgb_matrix::RGBMatrix; -using rgb_matrix::Canvas; - -int main(int argc, char *argv[]) { - RGBMatrix::Options defaults; - - defaults.hardware_mapping = "moduleair_pinout"; - defaults.rows = 64; - defaults.cols = 128; - defaults.chain_length = 1; - defaults.parallel = 1; - defaults.row_address_type = 3; - defaults.show_refresh_rate = true; - defaults.brightness = 100; - defaults.pwm_bits = 1; - defaults.panel_type = "FM6126A"; - defaults.disable_hardware_pulsing = false; - - - rgb_matrix::Color red(255, 0, 0); // Red color - rgb_matrix::Color bg_color(0, 0, 0); // Background color (black) - - Canvas *canvas = RGBMatrix::CreateFromFlags(&argc, &argv, &defaults); - if (canvas == NULL) - return 1; - - // Define the top-left corner of the square - int start_x = 10; // X coordinate - int start_y = 10; // Y coordinate - int square_size = 8; // Size of the square (8x8) - - // Draw a filled square - for (int x = start_x; x < start_x + square_size; ++x) { - for (int y = start_y; y < start_y + square_size; ++y) { - canvas->SetPixel(x, y, red.r, red.g, red.b); - } - } - - usleep(10000000); // Display for 10 seconds - - // Clean up - canvas->Clear(); - delete canvas; - return 0; -} diff --git a/matrix/test_forms_infinite.cc b/matrix/test_forms_infinite.cc deleted file mode 100644 index 234a3f3..0000000 --- a/matrix/test_forms_infinite.cc +++ /dev/null @@ -1,136 +0,0 @@ -/* - - __ __ _ _____ ____ _____ __ - | \/ | / \|_ _| _ \|_ _\ \/ / - | |\/| | / _ \ | | | |_) || | \ / - | | | |/ ___ \| | | _ < | | / \ - |_| |_/_/ \_\_| |_| \_\___/_/\_\ - - -Script to display a simple square on the matrix LED - -Pour compiler: -g++ -Iinclude -Llib test_forms_infinite.cc -o test_forms_infinite -lrgbmatrix - -Pour le lancer: -sudo /var/www/moduleair_pro_4g/matrix/test_forms_infinite -*/ - -#include "led-matrix.h" -#include "graphics.h" -#include -#include -#include -#include // For rand() -#include // For time() - -using rgb_matrix::RGBMatrix; -using rgb_matrix::Canvas; -using rgb_matrix::Color; - -// Global flag that can be used to exit the loop -volatile bool running = true; - -// Signal handler to catch Ctrl+C -static void InterruptHandler(int signo) { - running = false; -} - -int main(int argc, char *argv[]) { - RGBMatrix::Options defaults; - - defaults.hardware_mapping = "moduleair_pinout"; - defaults.rows = 64; - defaults.cols = 128; - defaults.chain_length = 1; - defaults.parallel = 1; - defaults.row_address_type = 3; - defaults.show_refresh_rate = true; - defaults.brightness = 100; - defaults.pwm_bits = 1; - defaults.panel_type = "FM6126A"; - defaults.disable_hardware_pulsing = false; - - // Set up signal handler for clean exit - signal(SIGTERM, InterruptHandler); - signal(SIGINT, InterruptHandler); - - // Seed the random number generator - srand(time(NULL)); - - Canvas *canvas = RGBMatrix::CreateFromFlags(&argc, &argv, &defaults); - if (canvas == NULL) - return 1; - - // Get canvas dimensions for position constraints - int canvas_width = canvas->width(); - int canvas_height = canvas->height(); - - // Square properties - int square_size = 8; // Size of the square (8x8) - int current_x = 10; // Initial X position - int current_y = 10; // Initial Y position - - // Create an array of colors to cycle through - std::vector colors = { - Color(255, 0, 0), // Red - Color(0, 255, 0), // Green - Color(0, 0, 255), // Blue - Color(255, 255, 0), // Yellow - Color(0, 255, 255), // Cyan - Color(255, 0, 255), // Magenta - Color(255, 255, 255), // White - Color(255, 127, 0), // Orange - Color(127, 0, 255) // Purple - }; - - int color_index = 0; - time_t last_change = time(NULL); - - // Draw initial square - Color current_color = colors[color_index]; - for (int x = current_x; x < current_x + square_size; ++x) { - for (int y = current_y; y < current_y + square_size; ++y) { - canvas->SetPixel(x, y, current_color.r, current_color.g, current_color.b); - } - } - - // Run indefinitely until interrupted - while (running) { - // Check if it's time to change color and position (every 2 seconds) - time_t now = time(NULL); - if (now - last_change >= 2) { - // Clear the previous square - for (int x = current_x; x < current_x + square_size; ++x) { - for (int y = current_y; y < current_y + square_size; ++y) { - canvas->SetPixel(x, y, 0, 0, 0); // Clear to black - } - } - - // Move to the next color - color_index = (color_index + 1) % colors.size(); - current_color = colors[color_index]; - - // Generate new random position, ensuring the square stays fully on screen - current_x = rand() % (canvas_width - square_size); - current_y = rand() % (canvas_height - square_size); - - // Draw the square with the new color at the new position - for (int x = current_x; x < current_x + square_size; ++x) { - for (int y = current_y; y < current_y + square_size; ++y) { - canvas->SetPixel(x, y, current_color.r, current_color.g, current_color.b); - } - } - - last_change = now; - } - - // Small sleep to prevent using 100% CPU - usleep(100000); // 100ms sleep - } - - // Clean up when interrupted - canvas->Clear(); - delete canvas; - return 0; -} \ No newline at end of file diff --git a/matrix/test_forms_noFail b/matrix/test_forms_noFail deleted file mode 100644 index e9f5ae4..0000000 Binary files a/matrix/test_forms_noFail and /dev/null differ diff --git a/matrix/test_forms_noFail.cc b/matrix/test_forms_noFail.cc deleted file mode 100644 index 81f7412..0000000 --- a/matrix/test_forms_noFail.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* - - __ __ _ _____ ____ _____ __ - | \/ | / \|_ _| _ \|_ _\ \/ / - | |\/| | / _ \ | | | |_) || | \ / - | | | |/ ___ \| | | _ < | | / \ - |_| |_/_/ \_\_| |_| \_\___/_/\_\ - - -Script to display a simple square on the matrix LED -sudo /var/www/moduleair_pro_4g/matrix/test_forms_noFail --led-no-hardware-pulse - -Pour compiler: -g++ -Iinclude -Llib test_forms_noFail.cc -o test_forms_noFail -lrgbmatrix - -*/ -#include "led-matrix.h" -#include "graphics.h" -#include -#include -#include - -using rgb_matrix::RGBMatrix; -using rgb_matrix::Canvas; - -volatile bool running = true; - -static void InterruptHandler(int signo) { - running = false; -} - -int main(int argc, char *argv[]) { - RGBMatrix::Options defaults; - - defaults.hardware_mapping = "moduleair_pinout"; - defaults.rows = 64; - defaults.cols = 128; - defaults.chain_length = 1; - defaults.parallel = 1; - defaults.row_address_type = 3; - defaults.show_refresh_rate = true; - defaults.brightness = 100; - defaults.pwm_bits = 1; - defaults.panel_type = "FM6126A"; - defaults.disable_hardware_pulsing = false; - - // Set up signal handlers for clean exit - signal(SIGTERM, InterruptHandler); - signal(SIGINT, InterruptHandler); - - // Try creating the matrix with a few attempts - Canvas *canvas = NULL; - int attempts = 0; - while (canvas == NULL && attempts < 3) { - canvas = RGBMatrix::CreateFromFlags(&argc, &argv, &defaults); - if (canvas == NULL) { - fprintf(stderr, "Creating canvas failed, attempt %d/3. Retrying...\n", attempts + 1); - attempts++; - usleep(500000); // Wait 500ms before retry - } - } - - if (canvas == NULL) { - fprintf(stderr, "Failed to create canvas after multiple attempts.\n"); - return 1; - } - - // Always clear the canvas first to reset any previous state - canvas->Clear(); - usleep(100000); // Small delay after clearing - - rgb_matrix::Color red(255, 0, 0); // Red color - - // Define the top-left corner of the square - int start_x = 10; // X coordinate - int start_y = 10; // Y coordinate - int square_size = 8; // Size of the square (8x8) - - // Draw a filled square - for (int x = start_x; x < start_x + square_size; ++x) { - for (int y = start_y; y < start_y + square_size; ++y) { - canvas->SetPixel(x, y, red.r, red.g, red.b); - } - } - - // Keep running until signaled - int seconds = 0; - while (running && seconds < 10) { - sleep(1); - seconds++; - } - - // Always ensure we clean up - canvas->Clear(); - usleep(100000); // Small delay after clearing - delete canvas; - - fprintf(stderr, "Display completed successfully.\n"); - return 0; -} \ No newline at end of file diff --git a/matrix/test_text b/matrix/test_text deleted file mode 100755 index 2492f92..0000000 Binary files a/matrix/test_text and /dev/null differ diff --git a/matrix/test_text.cc b/matrix/test_text.cc deleted file mode 100755 index 1724972..0000000 --- a/matrix/test_text.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* - - __ __ _ _____ ____ _____ __ - | \/ | / \|_ _| _ \|_ _\ \/ / - | |\/| | / _ \ | | | |_) || | \ / - | | | |/ ___ \| | | _ < | | / \ - |_| |_/_/ \_\_| |_| \_\___/_/\_\ - -Script to display a simple text on the matrix LED -sudo /var/www/moduleair_pro_4g/matrix/test_text - -Pour compiler: -g++ -Iinclude -Llib test_text.cc -o test_text -lrgbmatrix - -Pour lancer: -sudo /var/www/moduleair_pro_4g/matrix/test_text -*/ - -#include "led-matrix.h" -#include "graphics.h" - -#include -#include - -using rgb_matrix::RGBMatrix; -using rgb_matrix::Canvas; - -int main(int argc, char *argv[]) { - RGBMatrix::Options defaults; - defaults.hardware_mapping = "moduleair_pinout"; - defaults.rows = 64; - defaults.cols = 128; - defaults.chain_length = 1; - defaults.parallel = 1; - defaults.row_address_type=3; - defaults.show_refresh_rate = true; - defaults.brightness = 100; - defaults.pwm_bits = 1; - defaults.panel_type = "FM6126A"; - defaults.disable_hardware_pulsing = false; - - rgb_matrix::Color color1(255, 0, 0); // Red color for the first line - rgb_matrix::Color color2(0, 0, 255); // Blue color for the second line - rgb_matrix::Color bg_color(0, 0, 0); // Background color (black) - - int letter_spacing = 0; - - Canvas *canvas = RGBMatrix::CreateFromFlags(&argc, &argv, &defaults); - if (canvas == NULL) - return 1; - - // Load font - rgb_matrix::Font font; - if (!font.LoadFont("fonts/8x13.bdf")) return 1; - - // Define text for each line - const char *line1 = "Plouf Les amis!"; - const char *line2 = "Salut a tous!"; - - // Display first line with color1 - int x = 0; - int y1 = font.baseline(); // First line position - rgb_matrix::DrawText(canvas, font, x, y1, color1, &bg_color, line1, letter_spacing); - - // Display second line with color2 - int y2 = y1 + font.height(); // Second line position, just below the first line - rgb_matrix::DrawText(canvas, font, x, y2, color2, &bg_color, line2, letter_spacing); - - usleep(4000000); // Display for 4 seconds - - // Clean up - canvas->Clear(); - delete canvas; - return 0; -} \ No newline at end of file diff --git a/matrix/welcome_screen b/matrix/welcomeScreen/welcome_screen old mode 100755 new mode 100644 similarity index 100% rename from matrix/welcome_screen rename to matrix/welcomeScreen/welcome_screen diff --git a/matrix/welcome_screen.cc b/matrix/welcomeScreen/welcome_screen.cc similarity index 100% rename from matrix/welcome_screen.cc rename to matrix/welcomeScreen/welcome_screen.cc