google-coral / project-teachable

Example Project: Teachable Machine
https://coral.withgoogle.com/projects/teachable-machine/
Apache License 2.0
26 stars 15 forks source link

Wrong state of LEDs for devBoard #1

Closed LukasLoacker closed 5 years ago

LukasLoacker commented 5 years ago

I am using the project-teachable code on my devBoard. Unfortunetly i do have a minor problems with the LED output.

Examples of the porbable issue

Below i try to summerize whre the issue that tirggers a problem.

Incorrect code for GPIO.write() with wiggle

From my point of view the below code should switch on the LEDs one by one and turn them off.

def wiggleLEDs(self, reps=3):
    for i in range(reps):
      for i in range(5):
        self.setLED(i, True)
        time.sleep(0.05)
        self.setLED(i, False)

But the called function does the opposite:

def setLED(self, index, state):
    """Abstracts away mix of GPIO and PWM LEDs."""
    if type(self._LEDs[index]) is GPIO: self._LEDs[index].write(not state)
    else: self._LEDs[index].duty_cycle = 0.0 if state else 1.0

Due to the not state the result of the boolean is False, so the already switched off LED gets switched off again and vice versa.

Incorrect code for classifcation signal by LED

This seems also be ture for the fowolling function:

def setOnlyLED(self, index):
    for i in range(len(self._LEDs)): self.setLED(i, False)
    if index is not None: self.setLED(index, True)

Incorrect code for --testui

The above said is also ture for the following def:

  def testButtons(self):
    while True:
      for i in range(5):
        self.setLED(i, self.isButtonPressed(i))
      print('Buttons: ', ' '.join([str(i) for i,v in
          enumerate(self.getButtonState()) if v]))
          time.sleep(0.01)

If no button is pressed the expression self.isButtonPressed(i) returns False which gets converted by not state to a true boolean. The result is a light gleam of all LEDs at all time during the button test (sudo python3 teachable.py --testui).

Possible solutions

Info: Only for GPIO

Instead of sending the state var in the def and use not it's possible to get the current "actual" state of the GPIO by using self._LEDs[index].read()

def setLED(self, index):
    """Abstracts away mix of GPIO and PWM LEDs."""
    if type(self._LEDs[index]) is GPIO:
         self._LEDs[index].write(not self._LEDs[index].read())
    else: self._LEDs[index].duty_cycle = 0.0 if state else 1.0

Use code without not in setLED()

This one worked for me

def setLED(self, index, state):
    """Abstracts away mix of GPIO and PWM LEDs."""
    if type(self._LEDs[index]) is GPIO:
         self._LEDs[index].write(state)
    else: self._LEDs[index].duty_cycle = 0.0 if state else 1.0
mtyka commented 5 years ago

I just tried this on my devboard and it works correctly. Note that the LED GPIOs and PWMs are supposed to be wired as sinks, not sources. (i.e. the GPIO pin connects via the LED to 3.3V not to ground). So when the GPIO is set to high (i.e. 3.3V) the LEDs is off and when the GPIO is set to low (0V) the LED is ON, as there's now a voltage drop across it. Thus the logic in the code is inverted intentionally (self._LEDs[index].write(not state)). Check that your wiring is exactly as shown here: https://coral.withgoogle.com/projects/teachable-machine/

LukasLoacker commented 5 years ago

Thanks for your answer. True, I do have a different wiring (inclunding ground). I'll colse the issue.