REVLib 2024 burnFlash() Spark Max unreliabilty

I just got the chance to work on a MAXSwerve chassis, and I found I’m having issues with some of the settings burning to the Spark Maxes.

Specifically the conversion factor and/or the PID wrapping.

I’ve gotten it down to only a single parameter on a single Spark Max that doesn’t get flashed. I’ve set burnFlash to run for almost every setting, with a 500ms wait before actually calling the function every time. And its a different setting and a different Spark Max sometimes.

And I’ve been seeing an “invalid parameter id 16” in the Driver Station output (or something to that effect, I forget the wording but it was definitely 16).

Spark Maxes are running firmware version 1.6.3.

3 Likes

Could you post your code? I’m assuming it’s nothing different than what you said, I’m just curious

I don’t want to claim I have the answer here, but I will sympathise that we had similar issues with Spark Max’s not actually saving parameters when initialized in 2023. Cost us Provincial Champs :frowning:

Our solution is to query the Spark max after setting every parameter to see if it got through, and trying up to five times if not (and displaying a warning on the smartdash). It’s the first time I’ve used 3 way communication with a computer program.

1 Like

Edited the OP with links to the repos. Take a look at the PurpleLib repo, MAXSwerveModule and SparkMax classes.

@Greg_Needel Can we get some attention on this issue?

I’ve had numerous issues with REV software and API, which seems to be a major weak point in the REV user experience.

Not just this burnFlash() issue, but others as well.

  • hardware client crashing when I click the telemetry graph button
  • all devices disappearing from the GUI after updating firmware for a device over USB. Needs USB replug

Anyway we can keep this thread focused on the burnFlash() issue.

I discovered last year or the year before (not certain offhand) that burnFlash() is a blocking action on the controller. If you call SparkMax configuration API methods in quick succession with a burnFlash() call in the middle, the command after it will almost certainly fail silently. You can confirm this is what’s happening by capturing the return value (a REVLibError instance) to see what status it gives.

You should only call burnFlash() once at the end of initialization. I can’t really say when/where that might be in your code since you seem to have quite a bit of abstraction in place that I’m not (yet) familiar with.

I wish REVLib made use of java exceptions instead and allowed teams to just wrap it in a try/catch, but I’m sure that there’s likely some point where that would break down and be more problematic.


For your other issues, I haven’t seen them myself. There’s definitely issues (or at least room for improvement), but none that have been so detrimental that I’ve been completely stuck.

Yes we also had the same issue with our rev stuff on our robot, took forever to work out.

3683 also mentioned that they had the same issues.

I think we just ended up spamming the flash over and over again and hoping it worked, generally that seemed to work.

Not just at the end, several (we do 250) milliseconds after the end. We’ve had calls sent just before burnFlash() fail also.

Yep, what we do (inspired from 3005’s 2022 code) is:

  1. Check for errors after every set and redo if it fails
  2. Have a wait before and after the burn flashes
2 Likes

interesting… I’ve never seen it cause failure for calls right before it, only after. (Not saying you’re wrong. I just haven’t seen it)

I’ve seen your advice elsewhere as well, but anecdotally, adding more calls to burnFlash() after the settings that needed it seemed to help (with a 500ms wait). Before when I was only calling it once, basically every Spark Max on the drivebase would not have its conversion factors and/or PID wrapping set. But now, its (usually) just one Spark.

Seconding this and highly recommending it, we have only had one in-match occasion that we knew was a burnFlash error (claw did not invert itself) which led us to change some things that didn’t need to be burnt to flash rather than checking and re-applying the changes. This inversion was moved to inside of our claw’s setSpeed method and we also implemented the synchronized burning of flashes which I have rightfully named incinerateMotors.

Moving forward, I like the idea of checking the state of the spark and re-applying the parameter and might move to the 3 way communication method mentioned above.

1 Like