diff --git a/README.md b/README.md index ac21142..d37056c 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,20 @@ select the ["Enable remote sensor connections"](http://wiki.scratch.mit.edu/wiki #### Color - Who doesn't like rainbows? Especially blinking double rainbows. You can control the main LED color of Sphero via the color broadcast. + Who doesn't like rainbows? Especially blinking double rainbows. + +##### Color Name + + You can control the main LED color of Sphero via the color broadcast. - create a global variable named color_name and assign it a [color name](http://www.w3schools.com/html/html_colornames.asp), then broadcast "color". - you can also define new broadcasts with color_name where name is one of the valid color names, e.g. broadcast "color_cadetblue" or broadcast "color_crimson" - if you send it an invalid, or blank, color name, it will restore to the saved default color for your Sphero +- these broadcasts will update the 'sensor values' r, g, and b so you can have access to them via the sensor blocks + +##### RGB Color + + Create three global variables, r, g, and b and when these values change, the sphero will change. To see how it works, display the variables in scratch, and right click to turn them into sliders. Simply drag the sliders and see the color update. There is also an 'rgb' broadcast available too. ## Demo Scripts @@ -79,6 +88,8 @@ select the ["Enable remote sensor connections"](http://wiki.scratch.mit.edu/wiki [Sphero 2.0 controlled by Scratch(Japanese)](https://www.youtube.com/watch?v=qCeJ6_UKnk4) - [![Sphero colors via Scratch](http://img.youtube.com/vi/UoYA4e8f9Ns/0.jpg)](https://www.youtube.com/watch?v=UoYA4e8f9Ns) [Sphero colors via Scratch](https://www.youtube.com/watch?v=UoYA4e8f9Ns) +- [![RGB demo](http://img.youtube.com/vi/CcnS2AaIhMM/0.jpg)](https://www.youtube.com/watch?v=CcnS2AaIhMM) + [RGB demo](https://www.youtube.com/watch?v=CcnS2AaIhMM) ## Additional Resources @@ -86,3 +97,4 @@ select the ["Enable remote sensor connections"](http://wiki.scratch.mit.edu/wiki - [Scratch's Remote Sensor Control Protocol](http://wiki.scratch.mit.edu/wiki/Remote_Sensors_Protocol) - [Sphero API](http://orbotixinc.github.io/Sphero-Docs/docs/sphero-api/) - [Color Names](http://www.w3schools.com/html/html_colornames.asp) +- Two Scratch 2.0 projects dealing with RGB colors are the simple [Setting Color RGB](http://scratch.mit.edu/projects/2641383/) and the complex [RGB Colour Mixer](http://scratch.mit.edu/projects/187848/) diff --git a/scratch2sphero.rb b/scratch2sphero.rb index c7a974d..9ef353a 100755 --- a/scratch2sphero.rb +++ b/scratch2sphero.rb @@ -28,6 +28,7 @@ def initialize broadcast "backward" broadcast "color" + broadcast "rgb" broadcast "back_led_on" broadcast "back_led_off" @@ -36,13 +37,14 @@ def initialize @sphero_name = bluetooth_info.body.pack('C'*16).strip unless bluetooth_info.nil? # there seems to be some timing issue where the bluetooth_info isn't already ready in time when I'm asking for it so this is a quick hack to avoid an error # I'm also not sure what it'll do with extended character sets - @sphero_name = "-->unknown<--" if @sphero_name.nil? - # this needs more work... when it is unknown we don't seem to have communication with the ball -- somehow I think it is preventing the "Resource Busy" exception? + raise "Unable to get Sphero's name... Please Try Again" if @sphero_name.nil? puts "Connected to #{@sphero_name}" + user_led_color end - def on_sensor_update(name, value) # when a variable or sensor is updated - value = value.to_i if %w(speed initial_heading steps degrees).include? name + # when a variable or sensor is updated + def on_sensor_update(name, value) + value = value.to_i if %w(speed initial_heading steps degrees r g b).include? name if name == "speed" @speed = value elsif name == "initial_heading" @@ -53,9 +55,24 @@ def on_sensor_update(name, value) # when a variable or sensor is updated @degrees = value elsif name == "color_name" @color_name = value + elsif name == "r" + @r = value + elsif name == "g" + @g = value + elsif name == "b" + @b = value end puts "#{@sphero_name} -- #{name} assigned #{value}" - puts "#{@sphero_name} -- current_heading: #{@current_heading}, absolute_heading: #{@initial_heading + @current_heading}" + # whenever we set the color_name, do the color routine, and send the color broadcast + if name == "color_name" + color + broadcast("color") + end + if %w(r g b).include? name + rgb + broadcast("rgb") + end + #puts "#{@sphero_name} -- current_heading: #{@current_heading}, absolute_heading: #{@initial_heading + @current_heading}" end def broadcast_move @@ -90,6 +107,10 @@ def broadcast_backward def broadcast_color color end + + def broadcast_rgb + rgb + end def broadcast_back_led_on back_led_on @@ -141,17 +162,41 @@ def color(color_name=@color_name) begin puts "#{@sphero_name} -- color #{color_name}" @sphero.color color_name + rgb = @sphero.rgb_from_colorname color_name + sensor_update "r", rgb[:r] + sensor_update "g", rgb[:g] + sensor_update "b", rgb[:b] rescue => e puts "#{@sphero_name} -- unable to set color_name #{color_name}. #{e.message}" end end end + # sets the RGB color of the sphero via the @r, @g, and @b + def rgb(r=@r, g=@g, b=@b) + # I think the sphero gem's limit1() should probably handle these potential for nils... you can call rgb with the nils, it doesn't error but it puts the sphero in a non-communicative state + r = 0 if r.nil? + g = 0 if g.nil? + b = 0 if b.nil? + puts "#{@sphero_name} -- rgb #{r}/#{g}/#{b}" + sensor_update "r", r + sensor_update "g", g + sensor_update "b", b + @sphero.rgb r, g, b + end + # reset the color of the sphero to the persistent user selected colour def user_led_color() - puts "#{@sphero_name} -- Reseting color to user_led" + puts "#{@sphero_name} -- Resetting color to user_led" user_led = @sphero.user_led - @sphero.rgb user_led.body[0], user_led.body[1], user_led.body[2] + if user_led && user_led.body.nil? + puts "#{@sphero_name} -- No default user_led value" + else + @r = user_led.body[0] + @g = user_led.body[1] + @b = user_led.body[2] + rgb + end end # turns on the back LED so you know which way is forward. @@ -169,6 +214,15 @@ def back_led_off() end +class Sphero + # hack to give me the rgb used by a colorname + # the sphero itself won't return to me the current color (only the configured color it seems) + def rgb_from_colorname(colorname) + color=COLORS[colorname] + return {:r => color[:r], :g => color[:g], :b => color[:b]} + end +end + begin watcher = PrintRSC.new # you can provide the host as an argument watcher.sensor_update "connected", "1" @@ -176,5 +230,5 @@ def back_led_off() rescue Errno::ECONNREFUSED puts "\033[31m\033[1mError: Scratch may not be running or remote sensor connections are not enabled.\033[00m\n" rescue => e - puts "\033[31m\033[1mError: #{e.message}\033[00m\n" + puts "\033[31m\033[1mError: #{e.message}\n#{e.backtrace.join("\n\t")}\033[00m\n" end