Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -79,10 +88,13 @@ 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

- [Discuss scratch2sphero on the Scratch Forums](http://scratch.mit.edu/discuss/topic/21808/)
- [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/)
70 changes: 62 additions & 8 deletions scratch2sphero.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def initialize
broadcast "backward"

broadcast "color"
broadcast "rgb"

broadcast "back_led_on"
broadcast "back_led_off"
Expand All @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -169,12 +214,21 @@ 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"
loop { watcher.handle_command }
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