This commit is contained in:
Sven Vogel 2021-06-09 21:19:30 +02:00
parent 6230473ec6
commit b7d5b37fbc
20 changed files with 290 additions and 40 deletions

213
Arduino/LED_Matrix.ino Normal file
View File

@ -0,0 +1,213 @@
#include "Arduino.h"
#include "FastLED.h"
#define LED_TYPE WS2812B
#define DATA_PIN 6
#define MATRIX_MAX_WIDTH 20
#define MATRIX_MAX_HEIGHT 20
#define MATRIX_LED_MAX_COUNT (MATRIX_MAX_WIDTH * MATRIX_MAX_HEIGHT)
#define STD_WIDTH 10
#define STD_HEIGHT 10
#define STD_LED_MAX_COUNT (STD_WIDTH * STD_HEIGHT)
//#define DEBUG_PRINT_CALLBACK
#define WAIT while(!Serial.available());
uint8_t opcode = 99;
uint8_t width = STD_WIDTH;
uint8_t height = STD_HEIGHT;
uint32_t ledCount;
uint8_t gamma8(uint8_t x) {
uint32_t x2 = (uint32_t) x;
x2 = x2 * x2 * 258 >> 16;
return (uint8_t) x2;
}
CRGB leds[MATRIX_LED_MAX_COUNT];
typedef void (*FNPTR_t)();
uint8_t getByte() {
WAIT
return Serial.read();
}
uint16_t getWord() {
uint16_t highByte = getByte();
uint16_t lowByte = getByte();
return highByte << 8 | lowByte;
}
void scale() {
#ifdef DEBUG_PRINT_CALLBACK
Serial.println("scale called");
#endif
width = getByte();
height = getByte();
#ifdef DEBUG_PRINT_CALLBACK
Serial.print("Width: ");
Serial.println(width);
Serial.print("Height: ");
Serial.println(height);
#endif
uint16_t newLedCount = width * height;
if (newLedCount <= MATRIX_LED_MAX_COUNT) {
ledCount = newLedCount;
} else {
return;
}
#ifdef DEBUG_PRINT_CALLBACK
Serial.print("LEDs: ");
Serial.println(ledCount);
#endif
FastLED.addLeds<LED_TYPE, DATA_PIN>(leds, ledCount);
for (uint16_t x = 0; x < ledCount; x++) {
leds[x].r = 0;
leds[x].g = 0;
leds[x].b = 0;
}
FastLED.show();
}
void single() {
#ifdef DEBUG_PRINT_CALLBACK
Serial.println("Single called");
#endif
uint16_t index = getWord();
uint8_t green = gamma8(getByte());
uint8_t red = gamma8(getByte());
uint8_t blue = gamma8(getByte());
#ifdef DEBUG_PRINT_CALLBACK
Serial.print("Index: ");
Serial.println(index);
Serial.print("Red: ");
Serial.println(red);
Serial.print("Green: ");
Serial.println(green);
Serial.print("Blue: ");
Serial.println(blue);
#endif
leds[index] = CRGB(red, green, blue);
FastLED.show();
}
void image() {
Serial.readBytes((char*) leds, ledCount * 3);
for (uint16_t x = 0; x < ledCount; x++) {
leds[x].r = gamma8(leds[x].r);
leds[x].g = gamma8(leds[x].g);
leds[x].b = gamma8(leds[x].b);
}
FastLED.show();
}
void fill() {
#ifdef DEBUG_PRINT_CALLBACK
Serial.println("Called fill");
#endif
uint8_t green = gamma8(getByte());
uint8_t red = gamma8(getByte());
uint8_t blue = gamma8(getByte());
#ifdef DEBUG_PRINT_CALLBACK
Serial.print("Red: ");
Serial.println(red);
Serial.print("Green: ");
Serial.println(green);
Serial.print("Blue: ");
Serial.println(blue);
#endif
for (uint16_t x = 0; x < ledCount; x++) {
leds[x].r = red;
leds[x].g = green;
leds[x].b = blue;
}
FastLED.show();
}
void config() {
Serial.write(width);
Serial.write(height);
for (uint32_t i = 0; i < ledCount; i++){
Serial.write((uint8_t) leds[i].r);
Serial.write((uint8_t) leds[i].g);
Serial.write((uint8_t) leds[i].b);
}
}
FNPTR_t opcodeTable[] = {
scale, // opcode 0x00
single, // opcode 0x01
image, // opcode 0x02
fill, // opcode 0x03
config // opcode 0x04
};
void setup() {
ledCount = STD_LED_MAX_COUNT;
Serial.begin(9600);
FastLED.addLeds<LED_TYPE, DATA_PIN>(leds, ledCount);
for (uint16_t i = 0; i < ledCount; i++) {
leds[i].r = 0;
leds[i].g = 0;
leds[i].b = 0;
}
FastLED.show();
}
void loop() {
if (Serial.available()) {
#ifdef DEBUG_PRINT_CALLBACK
Serial.println("Opcode read in");
#endif
opcode = getByte();
#ifdef DEBUG_PRINT_CALLBACK
Serial.print("Opcode changed to:");
Serial.println(opcode);
#endif
if (opcode <= 4) {
opcodeTable[opcode]();
Serial.write(21);
}
}
}

View File

@ -37,6 +37,6 @@
</EmbeddedResource>
<EmbeddedResource Remove="SplashScreen.resx" />
<None Remove="Resources\pfüsikuh.png" />
<EmbeddedResource Include="Resources\pfüsikuh.png" />
<None Remove="Utils.cs~" />
</ItemGroup>
</Project>

View File

@ -99,7 +99,7 @@ namespace Matrix_App
if (((int) DateTime.Now.DayOfWeek) != 3)
return;
if (new Random().Next(0, 9) <= 1)
if (new Random().Next(0, 9) >= 1)
return;
using (Bitmap wednesdayFrog = new Bitmap(Properties.Resources.Frosch))
@ -646,7 +646,7 @@ namespace Matrix_App
{
if (Timeline.InvokeRequired)
{
// invoke on the comboboxes thread
// invoke on the combo-boxes thread
Timeline.Invoke(new Action(() =>
{
if (Timeline.Value < Timeline.Maximum)

View File

@ -1,5 +1,6 @@
using Matrix_App.PregeneratedMods;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Reflection;
using System.Text.RegularExpressions;
@ -85,8 +86,8 @@ namespace Matrix_App
};
button.Click += (sender, e) => OpenGeneratorUi(generator, matrix);
button.Image = CreateSnapshot(generator);
button.TextImageRelation = TextImageRelation.ImageAboveText;
button.Height = FilterPreviewHeight * 2;
button.TextImageRelation = TextImageRelation.ImageBeforeText;
button.Height = FilterPreviewHeight * 3 / 2;
anchor.Controls.Add(button);
}
@ -179,7 +180,7 @@ namespace Matrix_App
PlaybackTimer.Interval = _form.GetDelayTime();
PlaybackTimer.Enabled = true;
CreateDivider(controlPanel);
CreateDivider(controlPanel, 2);
foreach (var field in fields)
{
if (field.IsStatic || !field.IsPublic)
@ -187,23 +188,11 @@ namespace Matrix_App
var fieldValue = field.GetValue(_generator);
controlPanel.Controls.Add(GetFieldUi(field, fieldValue, _generator));
}
if (controlPanel.Controls.Count > 1)
{
CreateDivider(controlPanel);
var label = new Label() { Text = "Settings" };
label.Font = new Font(label.Font, FontStyle.Bold);
controlPanel.Controls.Add(label);
controlPanel.Controls.AddRange(GetFieldUi(field, _generator.GetType(), fieldValue, _generator));
CreateDivider(controlPanel, 1);
}
controlPanel.Controls.Add(_preview);
CreateDivider(controlPanel);
var playLabel = new Label() { Text = "Playback preview" };
playLabel.Font = new Font(playLabel.Font, FontStyle.Bold);
controlPanel.Controls.Add(playLabel);
FlowLayoutPanel southPane = new FlowLayoutPanel
{
@ -229,7 +218,7 @@ namespace Matrix_App
return success;
}
private static Control GetFieldUi(FieldInfo field, object? fieldValue, MatrixGifGenerator generator)
private static Control[] GetFieldUi(FieldInfo field, Type clazz, object? fieldValue, MatrixGifGenerator generator)
{
var panel = new FlowLayoutPanel
{
@ -238,10 +227,23 @@ namespace Matrix_App
AutoSize = true
};
var title = GetBetterFieldName(field.Name);
var description = new Label();
if (Attribute.GetCustomAttribute(field, typeof(UiDescriptionAttribute)) is UiDescriptionAttribute desc)
{
title = desc.title;
description.Text = desc.description;
description.ForeColor = Color.Gray;
description.Height += 10;
description.AutoSize = true;
}
panel.Controls.Add(new Label
{
TextAlign = System.Drawing.ContentAlignment.MiddleLeft,
Text = GetBetterFieldName(field.Name),
TextAlign = ContentAlignment.MiddleLeft,
Text = title,
Dock = DockStyle.Left,
Anchor = AnchorStyles.Top | AnchorStyles.Left,
Width = 100
@ -305,7 +307,7 @@ namespace Matrix_App
}
}
return panel;
return new Control[] {description, panel};
}
/// <summary>
@ -354,13 +356,13 @@ namespace Matrix_App
/// Adds a separating line to the controls
/// </summary>
/// <param name="controlPanel"></param>
private static void CreateDivider(Control controlPanel)
private static void CreateDivider(Control controlPanel, int height)
{
var divider = new Label
{
BorderStyle = BorderStyle.Fixed3D,
AutoSize = false,
Height = 2,
Height = height,
Width = 500
};

View File

@ -1,12 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
using static Matrix_App.GifGeneratorUtils;
namespace Matrix_App.PregeneratedMods
{
public class Boxblur : MatrixGifGenerator
public sealed class Boxblur : MatrixGifGenerator
{
[UiDescriptionAttribute(title: "Blur size", description: "The side length of the bounding square used to blur in pixels")]
public int blurSize = 2;
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)

View File

@ -7,12 +7,18 @@ namespace Matrix_App.PregeneratedMods
{
public sealed class ColorAdjust : MatrixGifGenerator
{
[UiDescriptionAttribute(title: "Tone offset", description: "Sets an additional offset to the pixels hue")]
public float hueOffset = 0.0f;
[UiDescriptionAttribute(title: "Saturation boost", description: "Decreases or increases saturation")]
public float saturationBoost = 0.5f;
[UiDescriptionAttribute(title: "Brightness boost", description: "Decreases or increases brightness")]
public float valueBoost = 0.5f;
[UiDescriptionAttribute(title: "Red boost", description: "Decreases or increases Red")]
public float redBoost = 0.5f;
[UiDescriptionAttribute(title: "Green boost", description: "Decreases or increases Green")]
public float greenBoost = 0.5f;
[UiDescriptionAttribute(title: "Blue boost", description: "Decreases or increases Blue")]
public float blueBoost = 0.5f;
private float boost(float x, float y)

View File

@ -7,6 +7,7 @@ namespace Matrix_App.PregeneratedMods
{
public sealed class Grayscale : MatrixGifGenerator
{
[UiDescriptionAttribute(title: "use Luminance", description: "Use luminance as defined by ITU-R BT.709 as grayscale output")]
public bool byLuminance = false;
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)

View File

@ -4,6 +4,7 @@ namespace Matrix_App.PregeneratedMods
{
public class RandomPixels : MatrixGifGenerator
{
[UiDescriptionAttribute(title: "Seed", description: "Just a seed for a bad deterministic random function")]
public int seed = 0;
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)

View File

@ -1,17 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
using static Matrix_App.GifGeneratorUtils;
namespace Matrix_App
namespace Matrix_App.PregeneratedMods
{
public class SimpleRainbow : MatrixGifGenerator
{
[UiDescription(title: "Radial", description: "Uses the angle to alter hues")]
public bool radial = false;
[UiDescription(title: "Saturation", description: "Overall saturation")]
public float saturation = 1.0f;
[UiDescription(title: "Brightness", description: "Overall brightness")]
public float value = 1.0f;
[UiDescription(title: "Hue rotation", description: "Offset for hue calculation")]
public float rotation = 0.0f;
protected override void ColorFragment(in int x, in int y,

View File

@ -0,0 +1,17 @@
using System;
namespace Matrix_App.PregeneratedMods
{
[AttributeUsage(AttributeTargets.Field)]
public class UiDescriptionAttribute : Attribute
{
public string title;
public string description;
public UiDescriptionAttribute(string title, string description)
{
this.title = title;
this.description = description;
}
}
}

View File

@ -11,16 +11,21 @@ namespace Matrix_App
[STAThread]
private static void Main()
{
SplashScreen.ShowSplashScreen();
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SplashScreen.ShowSplashScreen();
var designer = new MatrixDesignerMain();
SplashScreen.CloseForm();
designer.StartPosition = FormStartPosition.CenterScreen;
designer.WindowState = FormWindowState.Minimized;
designer.Show();
designer.WindowState = FormWindowState.Normal;
Application.Run(designer);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

@ -1,4 +1,5 @@
using System.Threading;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace Matrix_App
@ -17,8 +18,12 @@ namespace Matrix_App
Controls.Add(new Label()
{
Image = Properties.Resources.Pfüsikuh
Image = Properties.Resources.Pfüsikuh,
Size = new Size(Properties.Resources.Pfüsikuh.Width, Properties.Resources.Pfüsikuh.Height)
});
Size = new Size(Properties.Resources.Pfüsikuh.Width, Properties.Resources.Pfüsikuh.Height);
StartPosition = FormStartPosition.CenterScreen;
}
public static void ShowSplashScreen()

View File

@ -1 +1 @@
ee8b86baf58d13435f960406ec4b0be78d0cc26c
0e5f843b45897d8b4a3e6250399d748fbf87d606