wokwi / wokwi-features

Wokwi Feature requests & Bug Reports
https://wokwi.com
72 stars 17 forks source link

Is there a symbol definition to tell the compiler that the program is compiled using wokwi? #234

Closed bvandepo closed 10 months ago

bvandepo commented 2 years ago

As a teacher, I'm using wokwi in my class, for instance in https://bvdp.inetdoc.net/wiki/doku.php?id=cesitd1

In this context, I’m using shift registers to mimic PCF8574 gpio expanders that I used on my real hardware for another practical course: https://bvdp.inetdoc.net/wiki/doku.php?id=tdcom2

I wrote 2 HAL libraries that have the same functions prototypes so the students can use the libraries in the same way, but I have to manage different sets of files (having the same name and functions, which make the process prone to errors.)

I was wondering if there is a symbol defined by the compiler used on the wokwi server that I could use in my .cpp and .h file to adapt the behavior of the code to the context (I would just use a #ifdef COMPILED_FOR_WOKWI to embed the specific code for the simulation)

By the way, I wanted to add the PCF8574 to the list of components that Wokwi supports, I’ve watched your youtube videos that shows the graphical design of the components but I was not able to find the corresponding code so I’m completely lost about how to add such a component (which should not be too hard to add by mixing the behavior of DS1307 and shift registers). Is there some documentation about it? Or is it closed source?

urish commented 2 years ago

Hi again!

Great to see your course material, thank you for sharing it. Right now, there is no way to distinguish at compile time between running in Wokwi or on the real device.

You can implement a workaround and check this in runtime. One way to do it would be to connect a specific pin GPIO to GND in the simulation, configure that pin as INPUT_PULLUP, and then read the value and depending on the value (high or low) you know if you are running inside a simulation or not. Or would that not work for your use case?

Regarding the PCF8574 - I'd love if you added it. The part of the implements the logic for the parts is currently closed source, but I looked at the datasheet and I believe this is something I can quickly add.

As for the graphics, there's new way to create "boards". It's currently not very documented, but you can take a look at one of the existing boards which has some useful comments: https://github.com/wokwi/wokwi-boards/blob/master/boards/esp32-devkit-v1/board.json

Defining a new board is a matter of creating an SVG file with the graphics + JSON file which describes the pin locations and some other meta data. In your case, you don't need the "mcu" / "fqbn" parameters, nor the "leds" section (unless the carrier board has some power LED or similar).

Seems like this carrier board is pretty popular: https://www.waveshare.com/pcf8574-io-expansion-board.htm

But if there's another one you want to create, that's also good.

bvandepo commented 2 years ago

Hi, your idea of checking a pin is nice but would require one pin dedicated to that task, and I've many different shields that use the different pins so I can use them together, and I won't redesing it. It would be much simpler that you invoke the compiler using "gcc -D COMPILED_FOR_WOKWI" . If it's not possible on your side, I may configure this on mine, using "gcc -D COMPILED_FOR_REAL_HARDWARE" but then I'll have to check on my students' computers that they all have set it correctly...

I don't know how you manage the compilation, but if you have board management, you main simply add the COMPILED_FOR_WOKWI flag using my_board_for_my_cool_project.build.extra_flags=-DCOMPILED_FOR_WOKWI like shown in: https://forum.arduino.cc/t/how-to-specify-unique-compiling-options-for-multiple-sketches/679370/2

bvandepo commented 2 years ago

Regarding the PCF8574, if you decide to add it, it would be great if you can add an attribute to decide the i2c address range ( PCF8574 or PCF8574A) I'm not good about svg but If you do the hardware simulation code for the PCF8574, I can spend time on the graphic side (although I would probably be much more comfortable with the coding:) ) I'm sad to ear that the hardware is closed source, but I was a bit afraid of that as I've spent quite a lot of time trying to find the sources. May be it would be better to clearly identify what is open and closed as when I've looked at the youtube videos, I've though it was all open. Do you plan to open the sources someday? at least to a limited group? It would really improve your wokwi software! I'm a defender of opensource software, especially in academic institutions. In my institution, my colleagues use a proprietary software named Proteus for simulation with Arduino. From whar I’ve heard, I’ve understood that this software has an API for adding components. May be we could discuss about such approach for describing new hardware components. A few years ago, I’ve designed a tool to describe finite states machines models for hardware implementation on FPGA, https://hal.archives-ouvertes.fr/hal-02021357/document I had integrated the process with the ghdl simulator and I think this approach may be of interest for adding easily new components descriptions. Let me know if that is of interest for you. B.

urish commented 2 years ago

Hi, your idea of checking a pin is nice but would require one pin dedicated to that task, and I've many different shields that use the different pins so I can use them together, and I won't redesing it. It would be much simpler that you invoke the compiler using "gcc -D COMPILED_FOR_WOKWI" . If it's not possible on your side, I may configure this on mine, using "gcc -D COMPILED_FOR_REAL_HARDWARE" but then I'll have to check on my students' computers that they all have set it correctly...

I'd have to look into this. What is the actual use case for you? I mean, what kind of course would you compile differently based on whether it's running in simulation or not?

I'm sad to ear that the hardware is closed source, but I was a bit afraid of that as I've spent quite a lot of time trying to find the sources.

Some of the hardware is open as part of the AVR8js unofficial examples. Also, the AVR and RP2040 (for the Raspberry Pi Pico) simulation cores are open. I may be able to open additional parts in the future. Adding an API for creating new parts is something I've been thinking about, but for now it seems like it'd take more work to create, document and maintain this API compared to just creating the most popular parts.

I'll take a look at the document you attached, it does sound interesting. Do you have any information about the performance of these FSMs? How would you implemented something like the PCF8574 with these FSMs?

arduino12 commented 2 years ago

Hi,

I agree with @bvandepo - a WOKWI_SIMULATOR macro will be useful for many things..! For example- when using tone - the first call probably initializing somthing and it takes like 500ms to start producing the audio- I found out that adding delay(1000) to the setup() function solve this issue - but it will be much nicer to wrap it in:

void setup()
{
  pinMode(SPEAKER_PIN, OUTPUT);
#ifdef WOKWI_SIMULATOR
  delay(1000); // a start-up delay for the simulator to finish initializing audio stuff
#endif
}

So when I flash the same code with the Arduino-IDE - the delay(1000) will be omitted out. (Try commenting out the delay(1000) in my hatikva code setup() function and hear for yourself the first note gets too short).

Another usecase can be:

#ifndef WOKWI_SIMULATOR
  #include <some_private_lib.h> // will only compile in Arduino IDE
#endif

Or for example if I have a motor with an encoder- I want to simulate the encoder pulses if the WOKWI_SIMULATOR is defined and so on...

Describe the solution you'd like I want the Wokwi web simulator to add (in the background like the #include <Arduino.h>) a: #define WOKWI_SIMULATOR or #define WOKWI_VERSION (2021) or something like that- So the code can "know" if it is run inside the simulator or not by checking if this macro is defined..

You can implement a workaround and check this in runtime. One way to do it would be to connect a specific pin GPIO to GND in the simulation, configure that pin as INPUT_PULLUP, and then read the value and depending on the value (high or low) you know if you are running inside a simulation or not.

This is a nice hook - but it will be much better to implement this feature request instead (will also save GPIO).

Thanks!

urish commented 2 years ago

Thanks for the feedback @arduino12!

Regarding the tone() issue, can you please open a separate issue for this? Perhaps this is something I can fix in the simulator.

The reason I'm not very happy about introducing a special compiler macro for Wokwi, is that it may lead to situations where users work around issues instead of reporting them. It can get worse if library authors start depending on this at some point - so libraries implements things differently when they run on Wokwi.

Also, there are some thoughts about making it possible to flash the compiled firmware directly from the Web IDE. Compiling with different flags for the simulator / actual device means we'll have to build it differently for the actual device.

A possible solution that comes to mind is to make this macro optional - it won't be enabled by default, but users will be able to enable it if they need it for their projects.

Alternatively, let users specify a list of macros they want to set during the compilation. This is more powerful, as you'll be able to set any kind of macro, and possibly configure third-party libraries this way. On the other end, setting custom macros may slow down the compilation (since the Arduino CLI will have to recompile everything, and not just your project files).

Thoughts?

arduino12 commented 2 years ago

Happy to help Uri :)

Thanks for sharing your thoughts! - adding the option to flash and debug real arduino will be great! Adding the extra_flags option to the diagram.json or other config file as @bvandepo and you suggested seems to me like a good idea- also adding a default Wokwi macro to that list - so users can remove it or add more flags as sometimes needed by external libraries.

As long as the compilation-slowdown only occurs once - after the extra_flags changed - I think this is tolerable.

And finally, about other libraries using the Wokwi macro - if that ever happens - the maintainer must have a good reason- and I think he won't like it either- so as soon as the "bug" will be solved on the Wokwi side - I am sure he will happily remove the #ifdef Wokwi from his library code.

Another good use of the macro can be with neopixels - yesterday I made a small RGBDuino test and found out that I must set the neopixels brightness to 12% in real life because they are too bright and takes high current, but inside the simulator the 12% is very dim- So using the macro can do the 100% or 12% automaticly (I hope I have the time to make it a proper RGBDuino board on the future).

Thanks and waiting to see what you decide..!

urish commented 2 years ago

Adding the extra_flags option to the diagram.json or other config file as @bvandepo and you suggested seems to me like a good idea

Got it, I'll check to see what adding it involves

found out that I must set the neopixels brightness to 12% in real life because they are too bright and takes high current, but inside the simulator the 12% is very dim

Mind opening an issue for this too? We should probably apply gamma correction to NeoPixels, to make sure what you see in the simulation matches (more or less) what you get in real life

chrisisbeef commented 2 years ago

@urish asked on slack whether setting individual constant values was my only use-case for this ask -- here was my response

Right at this very second, but there will be more, for instance, I don't even want the code for the custom chips to compile locally, or be considered anything at all, so wrapping them in a

// my-custom.chip.c
#ifdef __WOKWI
// Some code
#endif 

something along those lines, I'm just spitballing right now, but I'm sure there may be lots of situations where that is the case I'm mostly interested in specifically the Preprocessor use of whether the code is running in a simulation or not; I don't want debug or test code that I would only use in a sim to even exist in the dev board or pcb firmware at all Build Time Ommision > Runtime Branching (especially where security is concerned) This could probably also be done by splitting a lot of things into different files and using naming conventions in my own build pipelines that I'm going to ultimately build around this stuff at some point, but that's a whole lot of work and convention is easily sidestepped by inattentive engineers

ArminJo commented 10 months ago

@urish may i ask, what is the state of the Wokwi compile macro request? My use case is, that I test my release version on Wokwi https://wokwi.com/projects/371657348012321793 , but everytime I copy the new version and compile it, I forget to uncomment the line 157 #define STANDALONE_TEST to run it on Wokwi, since I must simulate the CAN data. It is my fault, I know, but also an unnecessary compile and run cycle. There is no Wokwi bug or missing Hardware problem, the macro would be just convenient for easy (and reliable) testing 😀 .

Thank you very much for this awesome tool anyway!!! 🥇

Best regards Armin

urish commented 10 months ago

Thanks for the kind words @ArminJo.

We're not planning on adding it. For testing a release version, it probably makes more sense to use Wokwi for VS Code or the new Wokwi CLI.