gcormier / megadesk

Open-source IKEA Bekant controller board
GNU General Public License v3.0
719 stars 53 forks source link

found another "idle" status #46

Closed satrik closed 3 years ago

satrik commented 3 years ago

Hi,

I've just found out that my bekant (160x80) does neither send his idle as 96 nor as 0. Mine reports this state as 37. Just wanted to write it in here so that the 3rd state is known and can be found in this repo.

gcormier commented 3 years ago

Wow! Very interesting. I will add something to the firmware ASAP - do you have any captures we can add to the repo?

satrik commented 3 years ago

@gcormier well, I'm using a Wemos D1 mini and playing around with a mix of trainman419/yours and my own code^^ I've changed the lin.h and use SoftwareSerial to get the HardwareSerial (USB) for debugging output and this is the only I can "capture".

If I do this

Serial.println("node_a[2]");
Serial.println(node_a[2]);
Serial.println("node_b[2]");
Serial.println(node_b[2]);

right before the second switch (state) it outputs:

16:52:56.346 -> node_a[2]
16:52:56.346 -> 37
16:52:56.346 -> node_b[2]
16:52:56.346 -> 37

And afterwards I have to use if (node_a[2] == 0x25 && node_b[2] == 0x25) to get it working. That's the only thing that is different from the values in your code.

Please let me know if I can give you more information.

gcormier commented 3 years ago

Can I ask what the build date sticker on your controller is?

satrik commented 3 years ago

image

gcormier commented 3 years ago

Interesting. I have 2020-32 Rec: C. If we assume that's a week code, yours is only a bit newer than mine and same revision.

I will probably add this to the codebase to be safe for those who are purchasing them. We can keep an eye on things.

I do wonder if the motors have changed. Perhaps the idle status is communicated during the startup. If you have any way to take a look at one of the motors to get the model #, that would be great to see if it's the same. If so it could still be a firmware update on the motors, although I don't see why they would update the firmware just to change the idle code.

satrik commented 3 years ago

This is the only visible from the outside. image

tagno25 commented 3 years ago

Would it be possible that when toggleIdleParameter() is executed to set LIN_MOTOR_IDLE to node_a[2], as long as node_a[2] and node_b[2] are the same?

I know the variable is currently out of scope, it would require moving the declaration and then setting node_a and node_b to zero every loop. Would that work to find the idle status, and any future idle status values?

You wouldn't even have to check what the current LIN_MOTOR_IDLE value is and it saves 36 bytes of flash space when I tested it.

void toggleIdleParameter()
{
  if (node_a[2] == node_b[2])
  {
    LIN_MOTOR_IDLE = node_a[2];
    for (uint8_t i = 0; i < 3; i++)
    {
      beep(1, 2637);
      delay(10);
      beep(1, 2349);
      delay(10);
      beep(1, 2093);
      delay(10);
    }
  }

  EEPROM.write(2, LIN_MOTOR_IDLE);
}
satrik commented 3 years ago

While my testing I've seen that node_a[2] seems to be always the same as node_b[2]. For example, while pressing Up/Down it reports both as 34.

08:26:13.259 -> DOWN BTN
08:26:13.259 -> node_a[2]
08:26:13.259 -> 34
08:26:13.259 -> node_b[2]
08:26:13.259 -> 34

Not sure if it is the best way to just compare these 2 values.

To avoid toggling between the "hard" IDLE states, I've just written my code like this currently. Until now I don't have issues with this.

if (user_cmd != Command::NONE) {
    if (node_a[2] == node_b[2]) {
        if (node_a[2] == 0x25 || node_a[2] == 0x00 || node_a[2] == 0x60){
            state = State::STARTING;
        }
    }
}
gcormier commented 3 years ago

I'd be up for trying - I do have 2 desks that use different variant modes, so I can test how it works between the two :) Would you be up for submitting a pull request?

satrik commented 3 years ago

@gcormier I've created #48

Please check if I did remove the right things from the initAndReadEEPROM() function^^

gcormier commented 3 years ago

I've got it flashed and seems to work well on the 1st desk. I'm gonna soak test it for a little bit.

I'm also wondering how risky it would be to have it accept more new idle values. If we have a list of known non-idle states.

satrik commented 3 years ago

Im currently testing an extra function after lin init to get the IDLE value and store it in a variable. Seems to work so far, but still needs some testing.

Another thing I think about is to completly remove the IDLE state "check". I'm not 100% sure why it is needed in the second switch to find the next state 🤔 But I'm also not sure if it is a good idea to test it on my table 😄

gcormier commented 3 years ago

I mean, test away :)

The idea is that we'd rather not issue a move command (potentially in the opposite direction) before the motors have finished "their thing". So when letting go of up, you have that small decelleration period during which pushing the opposite direction does nothing.

That said, in actual use if you aren't trying to actually break something, it could be fine. You'd almost need to time the mashing of the buttons perfectly as the accel/decel is a very narrow window of time.

I do plan to run some flashing cables externally of the case so I can update firmware more easily to play around (I do use this desk daily for my job :) )

gcormier commented 3 years ago

newly made dev branch now has these changes incorporated. I kind of butchered things, but it's there now.

gcormier commented 3 years ago

dev branch merged into master which has this change - thanks for your work on this!