Jump to content

Ruby fertig!


borg

Recommended Posts

  • 2 weeks later...

Hi Borg

Ich habe erst vor einigen Tagen (als ich meine Tinkerforge Hardware bekommen habe) mit Ruby begonnen und komme mit den Callbacks des 20x4 LCD nicht klar.

folgender Code:

... übliche initialisierung aus dem  Beispielcode mit angepasster UID

# initialise display
lcd.clear_display
lcd.backlight_on

# I'm ready 
lcd.write_line 0, 0, 'ready...'

# until button 2 is pressed listen to button 1 callbacks 
until lcd.is_button_pressed(2)
  if lcd.register_callback BrickletLCD20x4::CALLBACK_BUTTON_PRESSED == 1
lcd.write_line 1,0, 'pressed 1'
  end
  if lcd.register_callback BrickletLCD20x4::CALLBACK_BUTTON_RELEASED == 1
    lcd.write_line 1,0, 'released 1'
  end
end
# clean up
lcd.clear_display
lcd.backlight_off
ipcon.destroy

 

Soweit funktioniert's aber ich bekomme von Button 1 keine Callbacks.

Habe ich das System nicht verstanden oder kann es sein, dass die Callbacks nicht korrekt funktionieren?

Das original Example will ebenfalls nicht, folgender Fehler:

C:\Users\admin>ruby C:\Users\admin\Desktop\tinkerforge_ruby_bindings_latest\examples\bricklet\lcd_20x4\example_button_callbacks.rb

C:/Users/admin/Desktop/tinkerforge_ruby_bindings_latest/examples/bricklet/lcd_20x4/example_button_callbacks.rb:19: syntax error, unexpected

keyword_do_block

lcd.register_callback BrickletLCD20x4::CALLBACK_BUTTON_PRESSED, do |i|

                                                                  ^

C:/Users/admin/Desktop/tinkerforge_ruby_bindings_latest/examples/bricklet/lcd_20x4/example_button_callbacks.rb:20: syntax error, unexpected

tSTRING_BEG, expecting keyword_do or '{' or '('

  puts "Pressed: #{i}"

        ^

C:/Users/admin/Desktop/tinkerforge_ruby_bindings_latest/examples/bricklet/lcd_20x4/example_button_callbacks.rb:21: syntax error, unexpected

keyword_end, expecting $end

 

Rubi 1.9.3 auf Windows 7

 

Vielen Dank!

Link zu diesem Kommentar
Share on other sites

Erstmal zum Syntaxfehler, der tritt nur unter Windows auf und hat mit der Block Syntax zu tun, die ich da verwenden. Unter Linux (Ruby 1.9.2) funktioniert

 

lcd.register_callback BrickletLCD20x4::CALLBACK_BUTTON_PRESSED, do |i|
  puts "Pressed: #{i}"
end

 

unter Windows muss es aber

 

lcd.register_callback(BrickletLCD20x4::CALLBACK_BUTTON_PRESSED) do |i|
  puts "Pressed: #{i}"
end

 

sein, warum auch immer. Ich werde das in der nächsten Release der Ruby bindings beheben.

 

 

Dein eigentliches Problem ist aber folgendes: Die folgenden Zeilen sind kein gültiger Ruby Code:

 

if lcd.register_callback BrickletLCD20x4::CALLBACK_BUTTON_RELEASED == 1
  lcd.write_line 1,0, 'released 1'
end

 

register_callback erwartet eine Callback ID als int (z.B. BrickletLCD20x4::CALLBACK_BUTTON_RELEASED) und einen Block (do |...| ... end)

 

Du verwendest es aber als wäre es ein Getter, das funktioniert nicht.

 

Eine richtige Verwendung von register_callback sieht z.B. so aus:

 

lcd.register_callback(BrickletLCD20x4::CALLBACK_BUTTON_PRESSED) do |i|
  puts "Pressed: #{i}"
end

 

Callback heißt, du übergibst der register_callback Methode einen Block und der wird immer dann ausgeführt wenn ein Callback vom Bricklet ankommt ohne weiteres Zutun von deiner Seite.

 

Callback bedeutet nicht, dass du aktiv in einer Schleife immer wieder fragst ob etwas passiert ist, das nennt mal Polling. Und genau das tut dein Beispiel im Prinzip.

 

Wenn ich deinen Code richtig verstehe willst du solange auf Button 1 reagieren bis Button 2 ein mal gedrückt wurde. Das kann man wie folgt tun:

 

sync = Queue.new

# register block for button pressed callback
lcd.register_callback(BrickletLCD20x4::CALLBACK_BUTTON_PRESSED) do |i|
  # if it's button 1 write a line
  if i == 1
    lcd.write_line 1, 0, 'pressed 1 '
  end
end

# register block for button released callback
lcd.register_callback(BrickletLCD20x4::CALLBACK_BUTTON_RELEASED) do |i|
  # if it's button 1 write a line
  if i == 1
    lcd.write_line 1, 0, 'released 1'
  # if it's button 2 push something to the queue so the pop below returns
  elsif i == 2
    sync.push nil
  end
end

# block until there is something to pop
sync.pop
ipcon.destroy

 

Ich benutze hier eine Queue als Synchronisationsmittel damit das Programm so lange am sync.pop steht bis Button 2 gedrückt wurde.

Link zu diesem Kommentar
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...