What's new
Pinball info

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

In Progress Mishmash Homebrew - Pt II - Playable Coffee Table

I don't want to be sending bits and locking on one thread and then doing the same from another. With this in mind, I need to reserve one CPU core for I/O operations and one core for all others, should be ok.
Ideally you would leverage the peripherals for I/O so the CPU doesn't get bogged down. A shift register can be implemented using a SPI for example.
 
You really dont need spi for the shift register. a single core can read it fast enough on normal pins. and still do all the other sh4t a pinball game needs. going dual core is the icing on the cake. - if you want to do a full lcd.m. esp32s can still do it if you bang the video stuff out to say a fruitPi
 
You really dont need spi for the shift register. a single core can read it fast enough on normal pins. and still do all the other sh4t a pinball game needs. going dual core is the icing on the cake. - if you want to do a full lcd.m. esp32s can still do it if you bang the video stuff out to say a fruitPi
I hear you Alan. I know it can work, I'm just theorising about pushing every last drop of power from the board whilst I still have the hood up ;)

I can see the dual core being the icing on the cake, but as you warned, it could make things more difficult when they don't need to be.
 
Boring update, just had a quick try on PlatformIO on VS Code...... oh, what a step up in usability that is over Arduino IDE. Looking forward to using that in anger.
 
So just updating on the code before the weekend ....

Globally, set up the handler for the new task running on core 0
1695399763005.png
In the setup() function, create the threaded task. This runs on core 0 with highest priority.
1695399814471.png
Here is that function that loops indefinitely. Note the delay(1), without that the Arduino falls over.
1695399906546.png
And that is all matrix reads, flipper activity, switch actions and coil fires processing on Core 0 at 1000 times per second. It would have been more but for that pesky delay ;)

1695399989806.png

Core 1 is now free for sound, lights, display and rules......it's getting exciting now :)

sub-update:

Flippers are working really well...

It's not using an interrupt (good shout Fubar) and they are still a part of the matrix (myPinballs), but as Alan says, plenty good enough for now. I will look to implement both in time.

This is the function called every loop after switch matrix is read.
1695400226194.png

They feel great and really throw the ball around - lovely :)
 
Last edited:
Yeah I suspect that IDE is ok for most things, small tests or whatever but for readability the theming alone there from VsCode makes it normal to read, faster.

This isn't a code review, but seeing as you're posting it. You should refactor out this "if (generalDebug)" in that one section. You only need one check for that in brackets and save typing and copy pasting.

Can you move this "genralDebug" flag into the methods or send in the flag to `println`? That way you don't have to type that every time and remove all the if statements.
 
Yeah I suspect that IDE is ok for most things, small tests or whatever but for readability the theming alone there from VsCode makes it normal to read, faster.

This isn't a code review, but seeing as you're posting it. You should refactor out this "if (generalDebug)" in that one section. You only need one check for that in brackets and save typing and copy pasting.

Can you move this "genralDebug" flag into the methods or send in the flag to `println`? That way you don't have to type that every time and remove all the if statements.
Thanks @dave I'll give it a shot. The aim is to get some super tidy code and it's the first time in years I feel like every time I sit down I learn something new and interesting.
 
Yeah I suspect that IDE is ok for most things, small tests or whatever but for readability the theming alone there from VsCode makes it normal to read, faster.

This isn't a code review, but seeing as you're posting it. You should refactor out this "if (generalDebug)" in that one section. You only need one check for that in brackets and save typing and copy pasting.

Can you move this "genralDebug" flag into the methods or send in the flag to `println`? That way you don't have to type that every time and remove all the if statements.
Just reviewed what you meant, blimey, I know better than that, how did I get to that 🤣🤣
 
Shopping list...sorry...another dull update...please ignore....

Relays to physically turn on high voltage only when needed.

A better mirror ball for part of the topper....oh yeah!!!!

Playfield protector
 
Last edited:
Not much progress this weekend, just a bit of pottering around.

Made progress on what I'm calling Core Machine Operations code. This is Flippers, Switches with Coil bindings and just plain switches. The flow here is:
  1. Scan Switch Matrix
  2. Flipper handling
  3. Switches with coil bindings (Pops and Slings). Fire the coils quickly.
  4. Turning off coils that have been on long enough.
  5. Switch hit processing (this will hopefully link into rules, modes etc later on).
  6. Temporary switch events to help with early testing
    1. Fire a coil (re-set a drop, kick ball out of saucer or out hole)
    2. Set DMD display text
    3. Score update
Services within this structure are Shift Registers, and Machine State processing at the moment.

Also started looking at the dot matrix display processing. Plan on doing this by having threads set up for several game states and setting them into suspended state until needed. That worked nicely out of the box which is nice. I am having issues with the MD_Parola library when I use its displayAnimate call, it tends to lock up activity on the rest of the ESP32 which is annoying in attract, but down right dangerous in game mode. Imagine a switch firing a coil and launching an animation - coils can stay on until the animation is down....no no no, not for me - no animations on dot matrix for now till I work out what's going on.
 
Saturday morning update, hoping to get a few hours in across today and tomorrow.

Not much change on the pinball (interesting bit), but plenty of things to help get the code going. The iterations were taking too long for me: , deploying to the device and then taking it to the machine, powering up, testing, monitoring the console line, turn off, back to code etc, etc -> therefor I have just completed the following:

I have implemented over the air (OTA) updates using a web browser. Lots of guides on t'internet to do this, but its really simple with the ESP32 to do this. (https://randomnerdtutorials.com/esp32-over-the-air-ota-programming/)

1696667381993.png

As I now have a web server running on the ESP32, I may as well write a single web page application (SPA) that can be used to read info on the machine states and trigger a few switches virtually.

1696667411847.png

Its not as complex as you would think, I create an empty web page, based on the brilliant W3CSS templates (https://www.w3schools.com/w3css/w3css_templates.asp). Then using simple AJAX calls (basically JavaScript in the page opening web urls, reading the response and then updating elements in the web page, real time) to get variables from the software, or to initiate functions in the code.

A quick chat about the method for this:

  1. In a separate header file, import the web libraries and start the server.
    1696668325933.png
    The web_dashboard.h and web_upload.h are the files with the HTML of my web pages.
  2. Define the function for the web operations, I'll be using this as a task pinned to a core later
    1696668411813.png
  3. Define the functions that will do the work when web urls are accessed.
    1696668476135.png
  4. Setup the task handler we will use for the task we pin to the core.
    1696668513516.png
  5. The WebOperationsFunction - these bits set up the listeners that can respond to URL calls. The bits in quotes is the URL, the bits without brackets are the action to take if the URL is hit. So basically, I'm calling functions. This is like the setup function in the main Arduino file, we will only call it once.
    1696668561066.png
  6. A few more of these listener setups and then the code that handles the firmware upload.
    1696668798005.png
  7. Then we make sure we dont spend our afternoon waiting for Wi-Fi to connect
    1696668839939.png
  8. The vTaskDelete(NULL) basically destroys the web server elements if we cant get Wi-Fi connected. Why have it running if its not usable.
  9. Then the looped bit of the task. The vTaskDelay(2) is important as without it, the ESP32 crashes because the task consumes too much compute time the onboard processes cant run. The delay allows them time to run.
    1696669049178.png
  10. We then go back to the main program file and setup the task in the setup() function
    1696669103964.png
  11. Finally the actual functions called in the listeners need their programming.
    1696669164657.png

As you can see, its really primitive at the moment, its not going to help responsiveness when the game is actually in use, but will be invaluable to help me focus on developing the important bits of the code and staying still.

Looking forward to making some progress this weekend, its been a few weeks since I have had capacity to get on with it :)

BUGS TO FIX:
ESP32 boards seem to have a flaw where when running Wi-Fi and only using the 5v in through board pins, it can brown out really easily. I have seen this. The second you only power via USB or add USB power its all good. Done some research and I think I'll need to connect the ground of the USB port to another ground pin to solve. I'll give this a go later down the line as I'm not going to be using it without a USB connected laptop for a while.


EDIT: Other progress

Started using GitHub to hold my code and manage the to-do list that gets longer and longer ;)
1696670186512.png
 
Last edited:
A quick video showing the workflow that has been created. Visual Studio Code + PlatformIO + ESP32 and the code.
 
There is no way this will end well, but I figured I may as well learn to make PCBs.....I have so much to learn, breadboard kit from Amazon me thinks......

Flippers to go direct to GPIO pins so I can use interupts
Break apart the shift registers into those for reading switch matrix, those for coils and then others (audio).

Not sure I'm brave enough to do MOSFET drivers yet.

1697132369825.png
 
A quick video showing the workflow that has been created. Visual Studio Code + PlatformIO + ESP32 and the code.

Build a program then upload it to computers firmware through a web UI?

Tried automating that process with Github?

Can run a self hosted runner, create workflow using that runner then when you push code to github or whatever there it can trigger your build on your runner. Put anything you want there.
 
Last edited:
my advice. dump eagle and use easyeda - it links to jlcpcb parts library, and easier to export the gerber files to jlcpcb and is a bit easier to use.
Quite right as always, it was a cinch - lets hope I get it right 1st time :hmm::rofl:
1697296079579.png
 
Build a program then upload it to computers firmware through a web UI?

Tried automating that process with Github?

Can run a self hosted runner, create workflow using that runner then when you push code to github or whatever there it can trigger your build on your runner. Put anything you want there.
That actually did cross my mind, problem is ideas are flowing faster than I have time to keep up with them. ;)
 
That actually did cross my mind, problem is ideas are flowing faster than I have time to keep up with them. ;)

You've done the build anyway, you just want the runner to run that and do that for you. Save ridiculous amount of time because you wipe out those steps and it gets tedious, time consuming.

I have a runner that builds and deploys intranet site in 1:30 using a github action. For me to do that by hand would take 10-30mins and that's if going fast. Yours isn't so bad, but still you can wipe out time if you are already using GH anyway.
 
You've done the build anyway, you just want the runner to run that and do that for you. Save ridiculous amount of time because you wipe out those steps and it gets tedious, time consuming.

I have a runner that builds and deploys intranet site in 1:30 using a github action. For me to do that by hand would take 10-30mins and that's if going fast. Yours isn't so bad, but still you can wipe out time if you are already using GH anyway.
Thanks @dave going to check it out 🙂
 
All coding and no play, time spend messing around today...

....thinking of making the DMD into and speaker cabinet, so tried that out today.

Measure up and mark out...

IMG_20231015_093554019_HDR.jpg
Sut some 20mm x 20mm wood for a frame, then glue ...
IMG_20231015_105815908_HDR.jpg

Then mount the DMD behind
IMG_20231015_130655646_HDR.jpg
 
Back
Top Bottom