I started the InMoov and MyRobotLab projects this past Spring. I REALLY thought all of this was going to be super simple and I was going just buy a 3D printer and in no time have all the parts and then shortly after be teaching my robot useful and entertaining things.  Well, this summer has been filled with learning all sorts of new things, which is great but not what I expected.  I for some reason can not just take a "Hello World" project, follow it and be content.  Take the InMoov project... I was just not satisfied with making the same robot as everyone else.  So I decided my InMoov needs a "Chappie" style head.  This has introduced its own unique set of challenges which requires solutions to problems noone else is tackling.  I am very greatful for the InMoov and MyRobotLab communities to provide support as I work on this project. 

I am still working on attaching the Chappie head to the neck and head base but I think I will be able to get it to work well enough for a first try and then I need to develop my 3D modeling skills for a better version 2 of this fork of the projects.  

I am also looking to use more i2c communication and I have these awesome eye displays I need to figure out how to controll through MRL.

Attached are some photos and Youtube links of some of my progress

Mouth Display Test:

https://www.youtube.com/watch?v=mVffkQ0Hdk4

Eye Display Test:

https://www.youtube.com/watch?v=hAVeKxwQm60

 

GroG

8 years 2 months ago

Reading your post I got a big smile !
It really refreshing to see something different ..

I like your attitude too :)

Ya .. robotics.. how long could it take? .. just print some stuff and teach it to go to the store and pick up some beer.
Funny how somethings after 6 billion years of evolution are easier to do vs make a machine do them.

So Welcome Kyle ! ... Welcome to a group who are in the same boat. And thanks for coming out of the closet.

Give us the specs on the I2C eye displays and I think we can borg them wiki wik.

Cheers,
GroG

Hello,

 

Once I figure out the best way to attach the Chappie head to the InMoov neck I will post all of my STL files to Thingiverse and post the link back in here.  I thought I had the head securely attached to the neck and tested the head servo and it shook his face off... literally. Sorry, no video of that.  

Thanks for your interest and stay tuned... I will share when I have something decent to share.

 

Kyle

GroG,

 

I am using these little gems:

https://www.amazon.com/gp/product/B01HHOETIA/ref=oh_aui_detailpage_o09_…

I am currently using the adafruit display library with a very hacky script..

I have not started trying to add any of this to the MRLComm.  I also have his antenna servos to control.  I was thinking if I could just wrap them all in to a command that was mood then I could set the eye displays and antenna all at once. So "Sad" would have my super cool sad eyes and the antenna would both be all the way down and back. "Mad" would have my super scary mad eyes and the antenna would be straight back, much like a cat right before it removes all of the skin off your arm for absolutely no reason... You get the idea.  

I do know that there is limited space on the arduino so I may have to move this to MRL and still be able to call these basic mood commands but all of the heavy lifting occurs in MyRobotLab and just sends what the Arduino needs to send on via the I2C bus. Oh, since my last(first) post I earned my Soldering Merit Badge and desoldered a jumper off on of the displays so that one now has the address of 0x3D while the other still has the original 0x3C.

Check out my new video:

https://www.youtube.com/watch?v=btYjq3vNh0o

Forementioned Hacky Script:

/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers
 
  Pick one up today in the adafruit shop!
 
This example is for a 128x64 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)
 
Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!
 
Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
 
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
 
#define OLED_RESET 1
#define OLED_RESET_2 2
Adafruit_SSD1306 display1(OLED_RESET);
Adafruit_SSD1306 display2(OLED_RESET_2);
 
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
 
 
#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 
#define SLEEPING 1
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };
  //B11111111, B11111111,
  static const unsigned char PROGMEM logo16_solid_glcd_bmp[] =
{ B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010,
  B10101010, B10101010 };
 
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
 
void setup()   {                
  Serial.begin(9600);
 
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display1.begin(SSD1306_SWITCHCAPVCC, 0x3C,true);  // initialize with the I2C addr 0x3D (for the 128x64)
  display1.display();
  display2.begin(SSD1306_SWITCHCAPVCC, 0x3D,true);  // initialize with the I2C addr 0x3D (for the 128x64)
  display2.display();
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  delay(2000);
 
  // Clear the buffer.
  display1.clearDisplay();
  display2.clearDisplay();
 
  drawWakeUp();
while (SLEEPING == 1) {
  delay(8000);
  drawBlink();
  delay(random(8000));
  drawMadEyes();
  delay(random(8000));
  drawEyes();
  delay(random(8000));
  drawLeftWink();
  delay(random(8000));
  drawRightWink();
  delay(random(8000));
  drawSadEyes();
}
  //drawBlink();
  //delay(6000);
 
  
  // draw a bitmap icon and 'animate' movement
  //testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}
 
 
void loop() {
  
}
void drawSadEyes(void) {
  display1.clearDisplay();
  display1.drawBitmap(42, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  // display1.drawBitmap(62, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  // display1.drawBitmap(82, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(42, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(62, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  // display1.drawBitmap(82, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(42, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(62, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(82, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.display();
 
  display2.clearDisplay();
  // display2.drawBitmap(42, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  // display2.drawBitmap(62, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(82, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  // display2.drawBitmap(42, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(62, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(82, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(42, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(62, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(82, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.display();
}
 
void drawEyes(void) {
  display1.clearDisplay();
  display1.drawBitmap(42, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(62, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(82, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(42, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(62, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(82, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(42, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(62, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(82, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.display();
  
  display2.clearDisplay();
  display2.drawBitmap(42, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(62, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(82, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(42, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(62, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(82, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(42, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(62, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(82, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.display();
}
 
void drawLeftWink(void){
  drawEyes();
  delay(400);
  drawClosedLeftEye();
  delay(400);
  drawEyes();
}
 
void drawRightWink(void){
  drawEyes();
  delay(400);
  drawClosedRightEye();
  delay(400);
  drawEyes();
}
void drawBlink(void) {
  drawClosedEyes();
  delay(400);
  drawEyes();
}
 
void drawWakeUp(void) {
  drawEyes();
  drawBlink();
  delay(400);
  drawBlink();
}
 
void drawMadEyes(void) {
  display1.clearDisplay();
  // display1.drawBitmap(42, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  // display1.drawBitmap(62, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(82, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  // display1.drawBitmap(42, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(62, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(82, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(42, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(62, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(82, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.display();
  
  display2.clearDisplay();
  display2.drawBitmap(42, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  // display2.drawBitmap(62, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  //display2.drawBitmap(82, 0,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(42, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(62, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  // display2.drawBitmap(82, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(42, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(62, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(82, 40,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.display();
}
 
void drawClosedEyes(void) {
  display1.clearDisplay();
  display1.drawBitmap(42, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(62, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(82, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.display();
  
  display2.clearDisplay();
  display2.drawBitmap(42, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(62, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(82, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.display();
}
 
void drawClosedLeftEye(void) {
  display1.clearDisplay();
  display1.drawBitmap(42, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(62, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.drawBitmap(82, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display1.display();
}  
void drawClosedRightEye(void) {
  display2.clearDisplay();
  display2.drawBitmap(42, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(62, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.drawBitmap(82, 20,  logo16_solid_glcd_bmp, 16, 16, 1);
  display2.display();
}
 

Mats

8 years 1 month ago

In reply to by kyle.clinton

Hi Kyle

I converted the SSD1306 library ( https://github.com/adafruit/Adafruit_SSD1306 ) to a service. It's very untested since I don't have a working hardware to test it on yet,

I created a small python script based on the script above to be able to get started with testing. 

# Initiate the Arduino
arduino = Runtime.createAndStart("Arduino","Arduino")
arduino.connect("COM3")
# Select the Arduino as controller for the OLED on bus 1 and i2c address 0x3D
oled = Runtime.createAndStart("OLED","OledSsd1306")
oled.setController(arduino,"1","0x3D")
# Using pin 4 to reset
resetPin = 4
arduino.pinMode(resetPin,"OUTPUT")
arduino.write(resetPin,1)
sleep(1)
arduino.write(resetPin,0)
sleep(1)
arduino.write(resetPin,1)
sleep(1)
# Demo based on examples from Adafruit
oled.begin(oled.SSD1306_SWITCHCAPVCC)
oled.display()
sleep(2)
oled.clearDisplay()
 
For the rest of the script, I think that the GFX ( graphics library ) also needs to be converted.
If the script works, you should see a splash screen on the OLED before it goes black again after 2 seconds.
 
/Mats