Jump to content



Photo
- - - - -

Preview release: Pinscape Pico


  • Please log in to reply
180 replies to this topic

#61 DDH69

DDH69

    Pinball Wizard

  • Platinum Supporter
  • 3,605 posts
  • Location:DOFLinx HQ, Adelaide

  • Flag: Australia

  • Favorite Pinball: Monster Bash

Posted 21 February 2025 - 11:51 PM

OK, so more building and testing.  To make it easier I have:
- Loaded a new Pico with 2 x GPIO outputs, one digital and one PWM

- Built a new circuit on my plug in board for easy changing and measurement.  The circuit is as per diagram in the documentation (modified below) with a LED and resistor on the MOSFET just like the path to R7., with R8=1K

 

Attached File  Circuit.jpg   33.97KB   10 downloads

 

I started with R7=620R as per the build of my 6x digital MOSFET channels

As expected current at point "A" as per your diagram is 0mA (and 0V over the resistor) for digital and PWM

With the oscilloscope top trace connected to the output of the UCC27524P (Point "A" on diagram) and the lower trace connected to the drain of the MOSFET (Point "B" on the diagram) set at 0.2uS per division

I see about 0.16uS for the UCC output to settle and 1.4uS for the MOSFET to switch (I gave it 7 divisions to be about 90%)

Attached File  620R.jpg   185.44KB   1 downloads

 

I then changed R7 to 270R (which I'm now thinking of using for my PWM channels)

Same oscilloscope connections

Same UCC time of 0.16uS as expected, and as expected the MOSFET switching is quicker at 0.8uS

Attached File  270R.jpg   189.04KB   5 downloads

 

R7=150R gives a turn on time of 0.7uS  (no photo)

 

> Are you running PWM at 20 kHz?

Yes, sticking with the defaults unless there is reason to change.  Happy to adjust for testing if it helps.

 

> That's easy enough to empirically test as well, just hook up a big motor or something and run it at various PWM levels to see if the MOSFET gets hot.

Agreed, but due to the PSU failure that blew up my TLC5940 build that has precipitated me getting so far into this, I don't have enough power on the bench to run a motor test, limited to my secondary 1A bench PSU at present.

 


DOFLinx
Contributions for equipment to help with ongoing DOFLinx development can be made here

#62 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 22 February 2025 - 07:19 AM

Thanks for doing all the detailed tests.  I think that all looks about like what I was expecting - the switching times seem to be about what the rough calculations say they should be.  The downside is that "as expected" means nothing jumps out to explain the mystery of what's killing the chips at lower gate resistances.

 

I spent a while looking through the TI support forum for the chip, and their application engineers consistently recommend gate resistors in the 1-5 Ohm range (which is just to reduce ringing; they seem entirely unconcerned about overcurrent protection).  So no answers there that I can find.

 

I plugged the 1us rise/fall time into a MOSFET power dissipation calculator, and it came up with about 2.5W with 12V on the drain side, and I think 5W with 50V on the drain.  The IRF540N data sheet Abs Max for power dissipation is 120-140W (!), depending on which data sheet you ask.  So I think the higher gate resistor is going to be fine - the chip might get a little warm throwing off 2-5W, but it's not anywhere near the limits.

 

> I then changed R7 to 270R (which I'm now thinking of using for my PWM channels)

 

I think that's a good plan.  Lower is better as far as the MOSFET switching heating goes, and 270R still gives you a margin of safety over the 150R cutoff point you zeroed in on, so it seems like a good meet-in-the-middle compromise.

 

>> Are you running PWM at 20 kHz?
> Yes, sticking with the defaults unless there is reason to change.  Happy to adjust for testing if it helps.
 
No need - I was just asking in case you were testing with a much higher PWM rate.  The driver chip power dissipation increases linearly with switching frequency, so if it turned out you were testing at 10 MHz, that would have thrown off all of the calculations, since I was assuming 20 kHz.  I think 20 kHz is about the optimal pin cab setting, because I would define optimal as the lowest rate that doesn't have objectionable side effects.  As far as the MOSFETs go, lower is better because it causes less switching-loss heating.  But anything below 200 Hz is bad for LED lighting (flicker), and anything below 20 kHz is bad for mechanical devices (acoustic coupling), so that's how I get to 20 kHz as the optimal rate.

Edited by mjr, 22 February 2025 - 07:27 AM.


#63 DDH69

DDH69

    Pinball Wizard

  • Platinum Supporter
  • 3,605 posts
  • Location:DOFLinx HQ, Adelaide

  • Flag: Australia

  • Favorite Pinball: Monster Bash

Posted 23 February 2025 - 04:37 AM

Mike, new issue for today.

 

When you add the 24th button and load to PS Pico it fails and triggers the watchdog timer.  It doesn't seem to matter what the key is, just the 24th key.  Ie I have setup the 24th + keys in the config then commented out keys at the top to keep it <=23 keys, so not a bad config for the 24th key.

 

I've attached a screen shot of my setup with 23 keys.

 

Attached File  23Buttons.png   59.5KB   8 downloads


DOFLinx
Contributions for equipment to help with ongoing DOFLinx development can be made here

#64 Suikazz

Suikazz

    Enthusiast

  • Members
  • PipPipPip
  • 133 posts

  • Flag: Hungary

  • Favorite Pinball: GoT

Posted 23 February 2025 - 11:26 AM

Mike, new issue for today.

 

When you add the 24th button and load to PS Pico it fails and triggers the watchdog timer.  It doesn't seem to matter what the key is, just the 24th key.  Ie I have setup the 24th + keys in the config then commented out keys at the top to keep it <=23 keys, so not a bad config for the 24th key.

 

I've attached a screen shot of my setup with 23 keys.

 

attachicon.gif 23Buttons.png

 

altough i'm not mike, i try to help and hunt down the issue.

What's your current setup exactly? i have the first iteration of the diy boards and 32 buttons as per default config running.

is it possible you skipped some firmware update or update of the tool?
i know, you're not a total beginner so i can only assume there's some "stupid" little mistake somewhere...



#65 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 23 February 2025 - 07:05 PM

DDH69 - I'll take a look.  It would help if you could send me an export of the full configuration, in case it's dependent on some other specific setting you have.  The version that would be most useful is the one that DOESN'T crash as-is, but DOES crash as soon you un-comment any one button.  (If I'm understanding your description correctly.)



#66 DDH69

DDH69

    Pinball Wizard

  • Platinum Supporter
  • 3,605 posts
  • Location:DOFLinx HQ, Adelaide

  • Flag: Australia

  • Favorite Pinball: Monster Bash

Posted 23 February 2025 - 11:57 PM

Thanks both.  Here is my working configuration.  Simply uncomment the last button to make it fail.  Then comment out any button to make it work again.  My main point in saying that is that its not the last button config causing the watchdog reset, its any button, hence my thought on being the 24th button.

{
    // Unit identification
    id:
    {
        unitNum: 1,
        unitName: "Arcade Dreams",
        ledWizUnitNum: 0,
    },

    serialPorts: {
        usb: {
            logging: true,      // enable logging on this port
            console: {
                enable: true,    // enable the interactive command line on this port
                bufSize: 8192,   // buffer size for console output
            },
        },
    },

    logging: {

        // Message filter.  This string selects which message types are
        // included in the log.  List all desired types, separated by
        // spaces; for example, "error warning" selects only error and
        // warning messages, disabling all others.  Available types:
        //
        //   debug      - debug messages; code path and internal state information useful when working on the firmware
        //   debugex    - extra debug messages; even more debugging detail, used for messages that tend to be repetitive,
        //                to allow filtering them out while still keeping the less voluminous debug messages
        //   error      - error messages
        //   warning    - warning messages (things that aren't errors but might cause unintended behavior)
        //   info       - general information and status messages
        //   vendor     - informational messages related to the USB vendor interface
        //   xinput     - informational messages related to the XInput (XBox controller emulation) interface
        //   config     - informational messages related to configuration and initialization
        //   tinyusb    - debugging messages from the Tinyusb library; enabled only when the firmware is compiled with
        //                Tinyusb debug messages enabled
        //   
        // "*" (asterisk) selects all message types
        // "~ x y" selects all EXCEPT x and y
        //
        // For a regular deployed system, you probably want the following:
        // errors, warnings, info, config.
        filter: "error warning info config",

        // Internal buffer size.  The device stores messages in an
        // internal buffer, so that it can pass them to attached
        // terminals at a pace that the serial connections can handle.
        // Messages are often generated at a faster rate than they can
        // be sent across the wire, and the Pinscape firmware makes a
        // point of never waiting for sloooow things like that, because
        // its most critical mission is to respond quickly to input
        // events from accelerometers, buttons, and plungers.  If the
        // buffer is too small, some messages might be discarded when a
        // flurry of activity occurs.  So the bigger the better, keeping
        // in mind that the Pico only has about 256K of RAM overall, and
        // lots of other features also want a piece of that.  Something
        // around 8K works pretty well, providing a cushion for the log
        // without crowding out any other features.
        bufSize: 16384,

        // Include timestamps, type codes, and color coding in log
        // messages?  The timestamps and type codes (which announce the
        // classification of each message: error, warning, info, etc)
        // are nice to have but take up room in that limited buffer
        // space we just allocated, so if you want to keep the buffer
        // smaller, you might turn them off.  The color coding also
        // takes up a bit of space, but it's really helpful because it
        // makes the error messages really stand out from the crowd.
        // The color coding uses ANSI escape sequences, which most
        // terminal programs understand, but which will look like
        // gibberish on terminals that DON'T recognize them.  If you
        // have problems with weird sequences like "[0;31m" appearing
        // all over the screen, try turning off the color coding.
        timestamps: true,
        typeCodes: true,
        colors: true,
    },

    // HID keyboard interface.  Enabling this allows you to assign
    // button inputs to send keyboard keystrokes to the PC.  This is one
    // of the foundational features of a pinball controller that
    // practically every virtual pin cab should include.  If you're not
    // using this Pinscape unit for button inputs, or if you don't wish
    // to map anything to keyboard input (for example, if you want all
    // buttons to generate gamepad input instead), it's okay to disable
    // this.
    //
    // Note that enabling this won't usually have any obvious visible
    // effect on the Windows side, since Windows does an excellent job
    // of making multiple keyboards all appear to work together as one
    // unified keyboard.  You will see a new keyboard appear in Device
    // Manager, but you probably won't notice any other effects.
    keyboard: {
        enable: true,
    },

    rgbStatusLight: {
        red: 21,             // GPIO port of RED color channel connection
        green: 22,           // GPIO port of GREEN color channel connection
        blue: 28,            // GPIO port of BLUE color channel connection
        active: "high",      // the pins are wired to the LED cathodes (GND side)
    },


    // Open Pinball Device HID.  This is a new alternative to the gamepad
    // interface that sends nudge, plunger, and button press information
    // to the PC via a dedicated, pinball-specific virtual device.  This 
    // only works with compatible simulators, so if you're using pinball
    // games that only accept the traditional joystick input, you can
    // enable BOTH the joystick and pinball device interfaces.  The goal
    // of the Open Pinball Device is to eventually replace the joystick
    // interface in all of the popular pinball simulators, so that you
    // don't have to make Pinscape Pico pretend to be a joystick.  Some
    // non-pinball games can behave erratically if an accelerometer is
    // constantly jiggling a joystick input, so we hope to eventually
    // eliminate these conflicts by making it unnecessary for pinball
    // controllers to impersonate joysticks.
    openPinballDevice: {
        enable: true,
    },

    // -------------------------------------------------------------------
    //
    // Button inputs.  The expansion board has 32 button input ports, 
    // wired through two PCA9555 chips.  The definitions below set up the
    // hardware sources for those 32 input ports.  The buttons are arranged
    // in the order of the pins on the button headers on the board.  (Note
    // that this doesn't exactly follow the order of the port labeling on
    // the PCA9555 chips.)
    //
    // For the boilerplate below, we've given each button a keyboard key
    // assignment, using the basic set of keys that Visual Pinball uses
    // by default.  You don't have to keep these, though - you can freely
    // rearrange them and/or change the assignments to actions other than
    // key presses, such as gamepad or XBox buttons.  I wasn't able to
    // come up with 32 standard VP buttons, so I assigned the last few
    // to gamepad buttons.  Gamepad buttons don't have any standard 
    // meanings in VP, but you can assign them functions in the VP setup
    // dialogs, or perhaps you could find uses for them in other games.
    //
    // The first four buttons are special in that they're wired through
    // GPIO ports, which makes them ideal for assigning to the flipper
    // buttons.  The key thing about GPIO-wired switches is that the
    // Pico can read GPIO ports faster than PCA9555 ports.  The time
    // difference is tiny, only about a millisecond, but the flipper
    // buttons are so critical to pinball play that even a small speed
    // difference might have an effect on the flipper feel.  The
    // flippers are the only buttons in a pinball simulation where this
    // small speed difference even remotely matters.  The expansion
    // board provides four direct GPIO switch inputs to accommodate the
    // double-stacked leaf switches used on some real pinball games that
    // have double flippers.  If you're using ordinary single-contact
    // leaf switches for your flipper buttons, you can use the extra
    // two GPIO ports for any other button inputs you wish - other than
    // the ultra-fast scan time, they behave just like the other button
    // inputs.
    //
    // Basic action formats:
    //
    //    action: { type: "key", key: "enter" },   // keyboard Enter key
    //    action: { type: "gamepad", button: 2 },  // gamepad button #2
    //    action: { type: "xInput", button: "a" }, // "A" button on XBox controller
    //
    buttons: [
        // Joystick
        { 
            source: { type: "74hc165", chip: 3, port: "D", debounceTimeOn:3000 },
            action: { type: "key", key: "left" },
        },
        { 
            source: { type: "74hc165", chip: 3, port: "C", debounceTimeOn:3000 },
            action: { type: "key", key: "right" }, 
        },
        { 
            source: { type: "74hc165", chip: 1, port: "F", debounceTimeOn:3000 },
            action: { type: "key", key: "up" }, 
        },
        { 
            source: { type: "74hc165", chip: 1, port: "E", debounceTimeOn:3000 },
            action: { type: "key", key: "down" }, 
        },
	//Top Row
        { 
            source: { type: "74hc165", chip: 2, port: "F" },
            action: { type: "key", key: "5" },
        },
        { 
            source: { type: "74hc165", chip: 2, port: "E" },
            action: { type: "key", key: "esc" },
        },
        { 
            source: { type: "74hc165", chip: 2, port: "H" },
            action: { type: "key", key: "f3" },
        },
        { 
            source: { type: "74hc165", chip: 2, port: "G" },
            action: { type: "key", key: "p" },
        },
        { 
            source: { type: "74hc165", chip: 2, port: "B" },
            action: { type: "key", key: "1" },
        },
        { 
            source: { type: "74hc165", chip: 2, port: "A" },
            action: { type: "key", key: "2" },
        },
	//Playfield
        { 
            source: { type: "74hc165", chip: 1, port: "G" },
            action: { type: "key", key: "left ctrl" },
        },
        { 
            source: { type: "74hc165", chip: 1, port: "H" },
            action: { type: "key", key: "left alt" },
        },
        { 
            source: { type: "74hc165", chip: 1, port: "A" },
            action: { type: "key", key: "space" },
        },
        { 
            source: { type: "74hc165", chip: 1, port: "B" },
            action: { type: "key", key: "y" },
        },
        { 
            source: { type: "74hc165", chip: 2, port: "D" },
            action: { type: "key", key: "z" },
        },
        { 
            source: { type: "74hc165", chip: 2, port: "C" },
            action: { type: "key", key: "x" },
        },
	//Flippers
        { 
            source: { type: "74hc165", chip: 1, port: "C" },
            action: { type: "key", key: "left shift" },
        },
        { 
            source: { type: "74hc165", chip: 1, port: "D" },
            action: { type: "key", key: "right shift" },
        },
	// Coin Door
        { 
            source: { type: "74hc165", chip: 0, port: "E" },
            action: { type: "key", key: "6" },
        },
        { 
            source: { type: "74hc165", chip: 0, port: "A" },
            action: { type: "key", key: "7" },
        },
	
	
	// Front Panel
        { 
            source: { type: "74hc165", chip: 0, port: "D" },
            action: { type: "media", key: "volUp" },
        },
        { 
            source: { type: "74hc165", chip: 0, port: "H" },
            action: { type: "media", key: "volDn" },
        },
        { 
            source: { type: "74hc165", chip: 0, port: "C" },
            action: { type: "key", key: "tab" },
        },
//        { 
//            source: { type: "74hc165", chip: 0, port: "F" },
//            action: { type: "key", key: "f6" },
//        },


	


    ],

    // -------------------------------------------------------------------
    //
    // Output Ports.  
    //
    outputs: [
	// High power outputs on board A
        {
            device: { type: "gpio", gp: 7, pwm: false },
        },
        {
            device: { type: "gpio", gp: 6, pwm: false },
        },
        {
            device: { type: "gpio", gp: 5, pwm: false },
        },
        {
            device: { type: "gpio", gp: 4, pwm: false },
        },
        {
            device: { type: "gpio", gp: 3, pwm: false },
        },
        {
            device: { type: "gpio", gp: 2, pwm: false },
        },
	// High power on board B
	// 
	
	
	// 4th Octet on board A
        {
            device: { type: "gpio", gp: 15, pwm: true  },
        },
        {
            device: { type: "gpio", gp: 14, pwm: true },
        },
        {
            device: { type: "gpio", gp: 13, pwm: true },
        },
        {
            device: { type: "gpio", gp: 12, pwm: true },
        },
        {
            device: { type: "gpio", gp: 11, pwm: true },
        },
        {
            device: { type: "gpio", gp: 10, pwm: true },
        },
        {
            device: { type: "gpio", gp: 9, pwm: true },
        },
        {
            device: { type: "gpio", gp: 8, pwm: true},
        },
	// 1st Octet on board A
        {
            device: { type: "workerPico", unit: 0, port: 16 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 17 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 18 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 19 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 15 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 14 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 13 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 12 },
        },
	
	// 2nd Octet on board A
        {
            device: { type: "workerPico", unit: 0, port: 11 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 10 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 9 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 8 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 7 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 6 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 5 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 4 },
        },
	// 3rd Octet on board A
        {
            device: { type: "workerPico", unit: 0, port: 3 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 2 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 1 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 0 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 23 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 22 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 21 },
        },
        {
            device: { type: "workerPico", unit: 0, port: 20 },
        },
	         {
             device: { type: "workerPico", unit: 1, port: 0 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 1 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 2 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 3 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 4 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 5 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 6 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 7 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 8 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 9 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 10 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 11 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 12 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 13 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 14 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 15 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 16 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 17 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 18 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 19 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 20 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 21 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 22 },
         },
         {
             device: { type: "workerPico", unit: 1, port: 23 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 0 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 1 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 2 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 3 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 4 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 5 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 6 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 7 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 8 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 9 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 10 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 11 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 12 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 13 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 14 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 15 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 16 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 17 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 18 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 19 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 20 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 21 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 22 },
         },
         {
             device: { type: "workerPico", unit: 2, port: 23 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 0 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 1 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 2 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 3 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 4 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 5 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 6 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 7 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 8 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 9 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 10 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 11 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 12 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 13 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 14 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 15 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 16 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 17 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 18 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 19 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 20 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 21 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 22 },
         },
         {
             device: { type: "workerPico", unit: 3, port: 23 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 0 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 1 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 2 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 3 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 4 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 5 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 6 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 7 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 8 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 9 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 10 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 11 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 12 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 13 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 14 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 15 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 16 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 17 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 18 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 19 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 20 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 21 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 22 },
         },
         {
             device: { type: "workerPico", unit: 4, port: 23 },
         },

    ],


    // -------------------------------------------------------------------
    //
    // IR Remote Control setup.
    // IR Receiver
    irRx: {
        gpio: 16,      // GPIO port for TSOP384xx OUT pin
    },


    // IR Transmitter
    irTx: {
        gpio: 17,      // GPIO port for IR LED output
    },


    // -------------------------------------------------------------------
    //
    // TV ON setup.  The expansion board implements the power-sensing
    // circuit required for the TV ON feature, which detects when the
    // main system power has just come on and uses this to send power-on
    // commands to the TVs.
    // 
//    tvon: {
//        powerDetect: {
//            sense: 26,
//            set: 27,
//        },

        // Delay time after system-wide power-on is detected, in
        // milliseconds.  The TV ON system waits this long before
        // pulsing the relay and/or sending the IR commands.
//        delay: 7000,
        
        // IR commands to send.  This is a sequence of command
        // strings, using the Pinscape universal remote control
        // coding format, to send after a power-on event.  You
        // should set these to the commands necessary to power up
        // your TV(s).
        //
        // The best way to figure out the code strings for your
        // particular TVs is to fire up the Config Tool, go to the
        // TV ON & IR screen, and press the remote buttons whose
        // codes you want to capture.  The IR screen shows commands
        // received on the IR sensor as they come in, using the
        // identical string format required here, so you can just
        // copy and paste codes from the IR window into this list.
        //
        // IR: [
        //     "03.02.7F3A21D0",   // turn on the first TV
        //     "07.00.6321",       // turn on the second TV
        // ],

        // Relay port.  You can hard-wire your TV's ON button to
        // a relay, and use one of the output ports to control the
        // relay.  If you do this, you have to tell the TV ON system
        // which port is wired to the relay, which you do here.
        // Set 'port' to the logical output port number from the
        // 'outputs:' array where the relay is attached.
        // 
        // relay: {
        //     port: 1,         // use the first logical output port
        //     pulseTime: 100,  // length of relay ON pulse, in milliseconds
        // },
//    },


    // -------------------------------------------------------------------
    //
    // Peripheral hardware setup.  Pinscape Pico has support for numerous 
    // external peripheral chips, including accelerometers, plunger
    // position sensors, GPIO expanders, shift registers, and PWM 
    // controllers.  Pinscape lets you attach each chip in various ways,
    // too, in order to accommodate many different combinations of chips.
    // That flexibility does come with a cost, though, which is that you
    // have to tell Pinscape how you're wiring things, because Pinscape
    // doesn't have many hard-coded assumptions about the wiring setup.
    //


    // I2C1 is used for all of the on-board peripherals on the DIY
    // Expansion Board, through GP6 (SDA) and GP7 (SCL).  All of the
    // peripherals in the Expansion Board design are compatible with a
    // 400,000 Hz data clock rate.
    //
    // The Pico's internal pull-up resistors on the SDA/SCL GPIO ports
    // must be disabled, because the peripheral power supply can be
    // disabled when the Pico has power, through a separate power
    // regulator dedicated to the peripherals.  This allows the Pico
    // to perform a hard reset on the peripherals under software control,
    // so that peripherals can be reset to a working state in the event
    // of any glitches without the need to unplug the whole board.  It's
    // potentially harmful to some devices to apply power to their I2C
    // pins when the chip's main power supply is off, so we don't want
    // the Pico to pull the I2C lines to 3.3V via its internal power.
    // We can prevent that by disabling the internal pull-ups.
    i2c1: {
        sda: 26,              // GPIO port of I2C0 SDA (serial data) connection
        scl: 27,              // GPIO port of I2C0 SCL (serial clock) connection
        speed: 400000,       // bus speed, bits per second
        pullup: false,       // disable internal pull-ups on the GPIO ports
    },

    i2c0: {
        sda: 0,
        scl: 1,
        speed: 400000,
        pullup: false,       // disable internal pull-ups on the GPIO ports
  //      enable: "on-demand",
    },

    // 74HC165 input shift registers.  The Expansion Board features
    // four of these chips, arranged in a daisy chain, for 32 input
    // ports.
    "74hc165": {
        nChips: 4,
        data: 18,
        shift: 19,
        load: 20,
        shiftClockFreq: 6000000,
    },

    // Pico PWMWorker - this is a Pico acting as a 24-channel I2C
    // PWM output controller, similar to a dedicated LED driver chip
    // like a TLC59116.  The DIY expansion board set features three
    // of these chips (one on the main board, two on the auxiliary
    // power board) for 72 output channels.
    //
    // The three Picos must be programmed with the Pinscape PWMWorker
    // firmware, which is included in the Pinscape Pico project.
    // Load PWMWorker.uf2 onto each Pico using the standard Pico Boot
    // Loader procedure.  In addition, you must manually set the I2C
    // addresses for the two Picos on the power board, because they
    // all get the same default address (0x30) when you first install
    // the PWMWorker firmware.  The Pinscape project includes a tool
    // for doing this as well, SetPWMWorkerAddr, which you run from
    // a Windows command prompt while the target Pico is in Boot
    // Loader mode.  (To put a Pico in Boot Loader mode, unplug the
    // Pico from all power and USB connections, then press and hold
    // the BOOTSEL button on top of the Pico while plugging it into
    // the USB port.  Release the button.  The Pico should now appear
    // as a virtual USB thumb drive on the Windows desktop, which
    // you can use for .UF2 firmware installation and for address
    // updates via the SetPWMWorkerAddr program.)
    workerPico: [
        // main board auxiliary Pico
        { i2c: 1, addr: 0x30, pwmFreq: 20000 },
        // power board Pico #1
        { i2c: 0, addr: 0x31, pwmFreq: 20000 },
        // power board Pico #2
        { i2c: 1, addr: 0x32, pwmFreq: 20000 },
        // power board Pico #3
        { i2c: 1, addr: 0x33, pwmFreq: 20000 },
        // power board Pico #4
        { i2c: 1, addr: 0x34, pwmFreq: 20000 },
    ],

}


DOFLinx
Contributions for equipment to help with ongoing DOFLinx development can be made here

#67 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 24 February 2025 - 12:14 AM

Great, thanks, I’ll give it a try. I suspect the test case isn’t “have 24 buttons”, but rather “have 24 buttons when you also have X”, where “X” is some other specific property of your config. If so it would be hard to guess what that was, but since you have a nice A/B test case where B is “add one button to A”, that should make it easier to reproduce.



#68 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 28 February 2025 - 12:34 AM

DDH69 - sorry for the delay following up on the button crash; I had some other things to attend to first.  I thought there'd be more leverage in improving the field diagnostics, so I added some crash site identification to the firmware. If you could give it a try with the 0.1.6 build on github, it should provide some new detail in the logging when it reboots into Safe Mode showing where the crash occurred.  You can get some extra detail by going into the USB CDC console (via a terminal emulator like PuTTY) and typing crashlog.  (You can reset back to regular mode first, since you probably don't have the CDC console configured for Safe Mode.)  That'll show the crash detail plus a hex dump of the stack, which might also be helpful.  Snip all of that and paste it here - hopefully that'll provide some more clues for what I should be looking for.

 

If you don't see a crash log in the Safe Mode startup messages, it should at least show the tail end of the log from the prior session, and that might also point to the locus.  In that case, try adding "debug" and "debugex" to the logging.filter section so you get as much detail as possible in the log.



#69 DDH69

DDH69

    Pinball Wizard

  • Platinum Supporter
  • 3,605 posts
  • Location:DOFLinx HQ, Adelaide

  • Flag: Australia

  • Favorite Pinball: Monster Bash

Posted 28 February 2025 - 02:44 AM

mjr, thank you for looking into this.  I believe your first instinct that it's A+B not just A or B is correct.  Using build 0.1.6 ....

- 0.1.6 crashed with the working configuration for 0.1.5

- Commenting out 3 more buttons (total of 4) got it working on 0.1.6

- I then tried adding the buttons back and removing outputs, with all buttons in, removing 5 outputs worked

- I have attached a zip with a current working 0.1.6 configuration with 4 x buttons commented out

- So two ways I found to get 0.1.6 working, reduce buttons by 4 or outputs by 5 ....... memory issue?

- Two logs in the attached zip, both are from the console connection of a good boot after a fail then displaying the crashlog.  One is with standard debugging the other has debug and debugex enabled

- not all of my worker Picos are connected yet so there are errors for those.  I wanted to point this out in case that is a contributor.  My thoughts have been that it is not since those errors are constant as I vary the number of buttons (unless errors use more of whatever we seem to running out of)

 

Attached File  Crash0.1.6.zip   10.95KB   4 downloads


DOFLinx
Contributions for equipment to help with ongoing DOFLinx development can be made here

#70 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 01 March 2025 - 12:01 AM

DDH69 - Thanks for all of that.  I think I tracked down the problem.  I think your instincts that it's memory-related were right.  Although from a place I didn't expect - it looks like the basic problem is that the JSON parse tree was a lot larger than it should have been.  That was crowding out other objects during the configuration process, leading to an out-of-memory condition and the crash.  I use my own custom JSON parser specifically to keep it as lightweight as possible on memory usage, but it turned out that there were a couple of things that weren't as optimized as I thought they were.  Up to now I hadn't noticed, since I hadn't tested any JSON input nearly as large as your 129-output-port setup.

 

I have a firmware patch you can try that should fix it, assuming this really was the root cause:

 

http://mjrnet.org/pi...28-json-fix.zip

 

This will hopefully make the JSON parse tree as efficient as it was supposed to be, so that no one should run into any similar problems with any kind of usable configuration.  (It will always be possible to blow out memory by creating a pathologically large configuration, but I think it's back to meeting the design objective of being efficient enough to handle any *realistic* configuration.)  The improved diagnostics should also help speed up the debugging process the next time something like this comes up.



#71 DDH69

DDH69

    Pinball Wizard

  • Platinum Supporter
  • 3,605 posts
  • Location:DOFLinx HQ, Adelaide

  • Flag: Australia

  • Favorite Pinball: Monster Bash

Posted 01 March 2025 - 03:11 AM

mjr, that has resolved the issue, thank you.

 

Glad to hear that its another issue resolved for those who follow.  Its funny how other people can find issues you hadn't even thought of when they get into their setups.  I suspect my setup is a larger one for the early days of Pico, but clearly well within its capability, so that's great.  You will be glad to know that I'll be quiet for a short time until I get the rest of my components.  :P


DOFLinx
Contributions for equipment to help with ongoing DOFLinx development can be made here

#72 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 01 March 2025 - 03:44 AM

> that has resolved the issue, thank you.

 

Great!  I thought that was probably it, but you can never be sure until it's tested.

 

> I suspect my setup is a larger one for the early days of Pico, but clearly well within its capability, so that's great.

 

It's definitely larger than anything I've tested so far.  You've got about 2X the output ports of my own expansion board designs, which I thought were pretty close to maxing out what people would actually want to build. It's great that you're pushing it a bit further.



#73 99nvbjed

99nvbjed

    Neophyte

  • Members
  • Pip
  • 2 posts

  • Flag: ---------

  • Favorite Pinball: Simpsons

Posted 13 April 2025 - 06:28 PM

Hi @mrj! 

Really appreciate this project, I'm new to the vpin world and it's a lot thanks to you.

When ordering a KL25Z from Mouser, I was affected by the "new and improved" USB-C KL25Z, missing the accelerometer and not being able to add it to the Pinscape Controller. When googling I found this project and I'm very intrigued.

 

Got a Pico on order, and I have a few accelerometers laying around, but non of the supported ones.

* MPU-6050

* ADXL345

Both might be a bit overkill for nudging, but they are easily available where I am.

 

If I were to develop support for one of these, which of the supported devices would you suggest to use as a basis for my code? https://github.com/m...e/Devices/Accel



#74 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 13 April 2025 - 06:59 PM

> Both might be a bit overkill for nudging, but they are easily available where I am.

 

I personally don't think there's such a thing as overkill for nudging. We're not measuring big inputs, so noise floor is kind of a big deal, and the low-end accelerometers are all pretty noisy.  The KL25Z accelerometer had much better noise specs than most of the currently available parts (such as the ones you mentioned), so I'm sad that it's not longer in production.  The trend seems to be towards noisier devices lately, unfortunately; I think it's because the high-volume buyers who drive the market are all makers of smart phones and watches, and they value ultra-low power consumption over all else, so they're willing to accept an increase in noise level to save a few microamps in standby mode.

 

> If I were to develop support for one of these, which of the supported devices

> would you suggest to use as a basis for my code?

 

The LIS3DH code should be a good starting point for either.  Both of the devices you mentioned use I2C, so everything should be very similar.  The main differences with these devices are usually in the initialization code to set up the device's configuration register settings.

 

The LIS3DH breakout boards are only about $5 in the US, so if it's similar in your location, you could save a lot of time by getting one of those to try out.  I think the specs on ADXL345 aren't quite as good as LIS3DH (and LIS3DH itself isn't that great, but it's better than a lot of the others currently in production).  I'm not familiar with MPU6050, but it's an obsolete part, so it's probably not worth too much effort writing code for it.



#75 99nvbjed

99nvbjed

    Neophyte

  • Members
  • Pip
  • 2 posts

  • Flag: ---------

  • Favorite Pinball: Simpsons

Posted 14 April 2025 - 07:40 PM

> The LIS3DH code should be a good starting point for either.  Both of the devices you mentioned use I2C, so everything should be very similar.  The main differences with these devices are usually in the initialization code to set up the device's configuration register settings.

 

> The LIS3DH breakout boards are only about $5 in the US, so if it's similar in your location, you could save a lot of time by getting one of those to try out.  I think the specs on ADXL345 aren't quite as good as LIS3DH (and LIS3DH itself isn't that great, but it's better than a lot of the others currently in production).  I'm not familiar with MPU6050, but it's an obsolete part, so it's probably not worth too much effort writing code for it.

 

Thanks for your input!

I've not been able to source the LIS3DH-board locally in Scandinavia, or even EU, but I did find a supplier in the UK so I've placed an order.

Before I found this project I was trying to integrate the ADXL345 as a HID-device using an Arduino to simulate a joystick input, but the further you go into the rabbit hole the more stuff you want to add, and the Arduino I used didn't have the capability (inputs, processing power etc), so I'm eagerly expecting the Pico to arrive tomorrow, and hopefully the UK order won't be held up too long in customs etc.



#76 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 14 April 2025 - 09:42 PM

> ... the further you go into the rabbit hole the more stuff you want to add, and the Arduino I

> used didn't have the capability (inputs, processing power etc)

 

I think you'll really like the Pico after working with the Arduino.  It's a really nice little platform, especially considering how inexpensive it is, and Raspberry Pi did a great job with the SDK.



#77 Suikazz

Suikazz

    Enthusiast

  • Members
  • PipPipPip
  • 133 posts

  • Flag: Hungary

  • Favorite Pinball: GoT

Posted 15 April 2025 - 12:03 PM

 

> The LIS3DH code should be a good starting point for either.  Both of the devices you mentioned use I2C, so everything should be very similar.  The main differences with these devices are usually in the initialization code to set up the device's configuration register settings.

 

> The LIS3DH breakout boards are only about $5 in the US, so if it's similar in your location, you could save a lot of time by getting one of those to try out.  I think the specs on ADXL345 aren't quite as good as LIS3DH (and LIS3DH itself isn't that great, but it's better than a lot of the others currently in production).  I'm not familiar with MPU6050, but it's an obsolete part, so it's probably not worth too much effort writing code for it.

 

Thanks for your input!

I've not been able to source the LIS3DH-board locally in Scandinavia, or even EU, but I did find a supplier in the UK so I've placed an order.

Before I found this project I was trying to integrate the ADXL345 as a HID-device using an Arduino to simulate a joystick input, but the further you go into the rabbit hole the more stuff you want to add, and the Arduino I used didn't have the capability (inputs, processing power etc), so I'm eagerly expecting the Pico to arrive tomorrow, and hopefully the UK order won't be held up too long in customs etc.

 

 

you can try Reichelt in germany ;)
they have the lis3dh:
https://www.reichelt...s_lis3dh-235486

 

shipping only for 1 item is pretty heavy but if you need other parts it is pretty reasonable ;)



#78 mkotek

mkotek

    Neophyte

  • Members
  • Pip
  • 9 posts

  • Flag: Poland

  • Favorite Pinball: Dragon's Lair

Posted 16 May 2025 - 08:33 PM

Thanks for your input!

I've not been able to source the LIS3DH-board locally in Scandinavia, or even EU, but I did find a supplier in the UK so I've placed an order.

Before I found this project I was trying to integrate the ADXL345 as a HID-device using an Arduino to simulate a joystick input, but the further you go into the rabbit hole the more stuff you want to add, and the Arduino I used didn't have the capability (inputs, processing power etc), so I'm eagerly expecting the Pico to arrive tomorrow, and hopefully the UK order won't be held up too long in customs etc.

 

You can always source the LIS3DH modules from AliExpress. They are like 4 USD and if you spend 10 USD, you get the 7 day shipping free.



#79 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 16 May 2025 - 11:23 PM

> You can always source the LIS3DH modules from AliExpress. 

 

The only problem with that is that, if the AliExpress sellers are anything like the random sellers on Amazon, it's probably hit-or-miss whether you'll get a working chip.  I've ordered a couple of random boards like that on Amazon and had about a 50% success rate at getting working parts.  Your luck might be better than mine, though.



#80 mkotek

mkotek

    Neophyte

  • Members
  • Pip
  • 9 posts

  • Flag: Poland

  • Favorite Pinball: Dragon's Lair

Posted 17 May 2025 - 12:38 PM

> You can always source the LIS3DH modules from AliExpress. 
 
The only problem with that is that, if the AliExpress sellers are anything like the random sellers on Amazon, it's probably hit-or-miss whether you'll get a working chip.  I've ordered a couple of random boards like that on Amazon and had about a 50% success rate at getting working parts.  Your luck might be better than mine, though.

Well, I source majority of my components from AliExpress and I have had maybe 2 situations where something was not working. But you can claim it for refund then and the only thing you loose is time, not money. I am always checking number of orders and if a shop sold 2000 orders I usually think it's legit.

Edited by mkotek, 17 May 2025 - 12:39 PM.