Skip to content

Conversation

@sshcrack
Copy link
Contributor

This will add the ability to mock RPI hardware. Mocking RPI hardware can be especially useful when the project is large and needs a lot of compile time, especially on the slow RPI 3 hardware. Building and debugging the program on a computer can speed up development significantly.

@sshcrack
Copy link
Contributor Author

Also I‘m quite unsure how to implement this. I think creating a new implementation is a good idea but should we make the RgbMatrix::Impl virtual so a mocking class can overwrite these methods?

@sshcrack
Copy link
Contributor Author

Also are there any emulators for seeing output of the led matrix? Like in the python implementation?

@hzeller
Copy link
Owner

hzeller commented Feb 28, 2025

I usually program all outputs against a Canvas implementation. Having said that, doing full animations with wait for sync and stuff is not possible with that.

We could consider virtual methods, but given that this might really be a compile-time choice (testing on an animation vs. 'production'), this might be unnecessary overkill. Let me think about this more.

Do you have a link to a project where you'd like to use this ?

@sshcrack
Copy link
Contributor Author

I'm using this for my led matrix application which has even support for plugins: Repo

@Tristan-Huen
Copy link
Contributor

Also are there any emulators for seeing output of the led matrix? Like in the python implementation?

I managed to make my own version using @hzeller's flaschen-taschen, ripping the code from the terminal plotter, and modifying the underlying matrix code. Currently it uses a run-time flag like the other options but would be way better as a compile-time choice imo. It's not the best and is really just a hacked-together thing I did out of need (funnily enough my project that I am using it for is the exact same concept as yours).

WindowsTerminal_bvHI0b2CqS

@sshcrack
Copy link
Contributor Author

Do you happen to have a repo link?

@Tristan-Huen
Copy link
Contributor

Do you happen to have a repo link?

I do not at the moment. There are some things that are janky and not currently working. For example, there's no compatibility with content-streamer or chains/mappers (I can at least pinpoint where changes need to be made). If you would like I can upload the code as-is if you would like to modify it and improve it. Otherwise, I could take some time to see if I could improve it.

@sshcrack
Copy link
Contributor Author

sshcrack commented Mar 2, 2025

Would be great if you could upload the code. I don't know if I'll be able to fix the missing features but I will try.

Alright I looked at the source code and I don't really understand how pixels are stored in bitplanes etc. It would be great if you could take some time!

@sshcrack sshcrack changed the title Add ability to mock RPI hardware Add RPI hardware emulator Mar 3, 2025
@sshcrack
Copy link
Contributor Author

sshcrack commented Mar 3, 2025

Okay, I've created a simple emulator, again there is no support for pixel mapping but it is working for my use case! Although the content streamer doesn't work yet as I haven't implemented the Serialize and Deserialize methods.

@sshcrack
Copy link
Contributor Author

sshcrack commented Mar 3, 2025

Alright it works on my machine™. There needs to be a lot more of testing and reviewing the code I think
Also what I've just noticed is the command line is getting parsed incorrectly (e.g. --led-emulator-scale=5 works but --led-emulator-scale 5 does not)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this file for now, don't know about the other pull request for CMake

@Tristan-Huen
Copy link
Contributor

Oh damn it seems you already implemented it from scratch by the time I saw this. Just from initial skimming it seems like you went with SDL which is actually nice since it removes the annoyances with the terminal (e.g. scaling).

Would be great if you could upload the code. I don't know if I'll be able to fix the missing features but I will try.

Alright I looked at the source code and I don't really understand how pixels are stored in bitplanes etc. It would be great if you could take some time!

The bitplane logic is something I don't understand fully as well. For the pixel mapping, another simulator I made using SFML gets around this by creating the window in the Impl::UpdateThread::Run function since the changes to the shared_pixel_mapper_ variable of the Impl class gets updated in the constructor by the calls to ApplyPixelMapper and ApplyNamedPixelMappers at the end:

RGBMatrix::Impl::Impl(GPIO *io, const Options &options)
: params_(options), io_(NULL), updater_(NULL), shared_pixel_mapper_(NULL),
user_output_bits_(0) {
assert(params_.Validate(NULL));
#if DEBUG_MATRIX_OPTIONS
PrintOptions(params_);
#endif
const MultiplexMapper *multiplex_mapper = NULL;
if (params_.multiplexing > 0) {
const MuxMapperList &multiplexers = GetRegisteredMultiplexMappers();
if (params_.multiplexing <= (int) multiplexers.size()) {
// TODO: we could also do a find-by-name here, but not sure if worthwhile
multiplex_mapper = multiplexers[params_.multiplexing - 1];
}
}
if (multiplex_mapper) {
// The multiplexers might choose to have a different physical layout.
// We need to configure that first before setting up the hardware.
multiplex_mapper->EditColsRows(&params_.cols, &params_.rows);
}
Framebuffer::InitHardwareMapping(params_.hardware_mapping);
active_ = CreateFrameCanvas();
active_->Clear();
SetGPIO(io, true);
// We need to apply the mapping for the panels first.
ApplyPixelMapper(multiplex_mapper);
// .. followed by higher level mappers that might arrange panels.
ApplyNamedPixelMappers(options.pixel_mapper_config,
params_.chain_length, params_.parallel);
}

@sshcrack
Copy link
Contributor Author

sshcrack commented Mar 6, 2025

Yeah, I just ended up implementing a virtual frame buffer which the emulator update thread can read easily

@sshcrack
Copy link
Contributor Author

sshcrack commented Mar 7, 2025

Oh, didn't mean to push this to this PR, will undo
Also I tested this PR, maybe a notice in the README is missing but I think the code should be done

This reverts commit 898abff, reversing
changes made to dd5f5ff.
@WardBrian
Copy link
Contributor

Also are there any emulators for seeing output of the led matrix? Like in the python implementation?

https://github.com/ty-porter/RGBMatrixEmulator

@sshcrack
Copy link
Contributor Author

Also are there any emulators for seeing output of the led matrix? Like in the python implementation?

https://github.com/ty-porter/RGBMatrixEmulator

I should've clarified: I meant if there is a cpp based emulator so outputs of a cpp program can be seen

@marcmerlin
Copy link
Collaborator

This looks interesting, but indeed I'm going to leave it to @hzeller
For the C interface, I handled this a different way. I have a framebuffer::gfx 2D API which I recommend since it works against many backends, and I added a linux/sdl backend to display directly on my laptop without hardware:
https://marc.merlins.org/perso/arduino/post_2020-01-24_Running-Arduino-code-with-2D-FastLED_-Adafruit_GFX_-and-LEDMatrix-displays-on-Linux.html

then the same code can run on rpi with this lib:
https://marc.merlins.org/perso/arduino/post_2020-01-01_Running-FastLED_-Adafruit_GFX_-and-LEDMatrix-code-on-High-Resolution-RGBPanels-with-a-Raspberry-Pi.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants