Companion Bot for Jr STEAM
A cute and interactive shoulder pet robot for Jr STEAM kids from 7 yo. Yes, I said 7!
Things used in this project
Software apps and online services
Hand tools and fabrication machines
3D Printer (generic)
These cute little creatures are indeed a perfect combination of all the components of STEAM teaching, like:
S: How do you capture a physical phenomenon like a sound?
T: How do OLED displays work?
E: How to use Onshape to create a robot body and its accessories?
A: How to design a cutting pattern and sew the "skin" of a robot?
M: How to use a Cartesian coordinate system to program "OLED eyes"?
LET'S START WITH THE RESULT!
As a reminder, here are the conditions that led to this result:
Students ages 7-9,
10 hours for the whole project,
A group of 9 students with 1 robot for each.
REAL OPEN-SOURCE DESIGN WITH ONSHAPE
Of course, you will find all the STL files needed for this project on this page.
But the interest is elsewhere...
In my opinion, the real open-source aspect of a project lies in the fact to put at the disposal of the whole community natively modifiable files and not "dead" files like STLs.
In addition to having access to the native files for modification, Onshape also allows everyone to have access to the model creation tree and to learn from the design process. This is a very effective method with my students!
Just use the Rollback Bar to go through the entire design process:
The body integrates two openings for the "OLED eyes" and five slots for servomotors.
The lateral ones are meant for "arms", the bottom ones for "legs" and the rear one for a "tail". But let the kids imagine other amazing things!
You also have thin slots to use velcro straps to attach the bot to your t-shirt if needed.
The two OLED screens are fixed to the body thanks to four Nylon M2x12 screws plus nuts. DON'T TIGHTEN the nuts too much, screens are quite fragile.
Here's the basic wiring of the screen to the board:
As we are working with young kids here, the use of an IO shield makes the wiring easier. The shield gives you direct access to the I2C bus (P19 and P20).
As our Companion Bot is meant to show emotions by interacting with us, I used the table below to define Inputs and Outputs related to a specific emotion.
Please note that as the screens share the same I2C address, the two eyes will display the same "emotion".
We used Piskel to simulate emotions before programming them. It's also an easy way to collect useful coordinates for programming.
In order to use the OLED screens with the microbit.org online editor, you will have to add the following extension:
The HEX file corresponding to the video demo can be found here.
The Python-translated code is attached to this page.
Letting the kids think about the sewing pattern is a very nice 3D visualization exercise. They should start by using paper first.
Onshape is here very helpful to determine the exact dimensions of the bot, especially when you integrate fillets or curves.
There're multiple ways to create the "skin" sewing pattern of the robot, I'm sharing with you the one we used:
Custom parts and enclosures
Companion Bot for Jr STEAM - Tail
Companion Bot for Jr STEAM - Lid
Companion Bot for Jr STEAM - Body
SSD1306 to micro:bit.
Jr STEAM Companion Bot #2
Copy and paste the code in MS MakeCode for upload on your micro:bit board.
def SLEEP(): global to_close, wakeup while to_close < 23: OLED12864_I2C.hline(23, to_close, 15, 1) to_close += 1 basic.pause(500) wakeup = 1 def GIGGLE(): global to_mid while to_mid < 16: OLED12864_I2C.hline(23, to_mid, 15, 1) to_mid += 1 basic.pause(500) for index in range(8): servos.P1.set_angle(90) basic.pause(100) servos.P1.set_angle(130) basic.pause(100) def on_button_pressed_a(): global to_close OLED12864_I2C.clear() basic.show_leds(""" . . . . . . . . . . # # # # # . . . . . . . . . . """) for index2 in range(1): OLED12864_I2C.rect(6, 3, 56, 28, 1) OLED12864_I2C.rect(23, 8, 38, 23, 1) to_close = 9 SLEEP() OLED12864_I2C.clear() OLED12864_I2C.show_string(0, 2, "ZZZZZZZZZZZZ", 1) basic.pause(2000) servos.P1.set_angle(30) input.on_button_pressed(Button.A, on_button_pressed_a) def on_logo_pressed(): global to_mid OLED12864_I2C.clear() to_mid = 9 OLED12864_I2C.rect(6, 3, 56, 28, 1) OLED12864_I2C.rect(23, 8, 38, 23, 1) GIGGLE() basic.pause(2000) soundExpression.giggle.play_until_done() OLED12864_I2C.clear() input.on_logo_event(TouchButtonEvent.PRESSED, on_logo_pressed) to_mid = 0 to_close = 0 wakeup = 0 music.set_built_in_speaker_enabled(True) OLED12864_I2C.init(60) servos.P1.set_angle(110) wakeup = 0 def on_forever(): if input.sound_level() > 100 and wakeup == 0: OLED12864_I2C.rect(6, 3, 56, 28, 1) OLED12864_I2C.rect(23, 8, 38, 23, 1) for index3 in range(4): servos.P1.set_angle(90) basic.pause(200) servos.P1.set_angle(130) basic.pause(200) basic.show_leds(""" . . . . . # . . . # # . . . # . # # # . . . . . . """) basic.pause(2000) basic.forever(on_forever)