IKEA Spöke/Spoke(ghost)

  • I have rebuilt IKEA Spöke(ghost) to be used with MyS and Pro Mini 5V
    I replaced LED with 4 pcs WS2812B LED's.
    Removed all components on POWER PCB, I only use the PCB to get 5V.
    Button is removed.
    No battery is used, only power from 5v adapter. To drive nRF I used step-down 5->3.3V
    When you solder the Ground pin on the PCB, check carefully from where you take the GND, when the plug is inserted you will NOT get GND from all GND spots/places.
    If you will build this think about this/next version:
    Use more LED's, maybe 6 or 8. Change in sketch!!
    Remove LED on step-down and LED on Pro Mini, will light up alot during night if lamp is off
    Add function for button, so you can start it without access to your controller
    Add Repeater function, why not it is on power all the time

    Video: https://youtu.be/sNSBahc-79s
    Link to IKEA Spoke http://www.ikea.com/gb/en/products/childrens-ikea-products/children-3-7/childrens-lighting/spöka-led-night-light-animal-white-turquoise-art-00150985/

    I use the color to tell my kids when it is OK to wake up :), sometimes they wake up at 6 am!!. When time is ok to go up from bed it shows green otherwise it shows red/purple light during whole night.

    To put the silicon back I forst used a lot of power, then I tried with alcohol it was a piece of cake. The alcohol will vaporize.
    This is the sketch

    /*PROJECT: MySensors / RGB test for Light & Sensor
     DATE: september 27, 2015/ last update: October 10, 2015
     FILE: AWI_RGB.ino
     LICENSE: Public domain
     Hardware: Nano and MySensors 1.5
      uses Fastled library with NeoPixel (great & fast RBG/HSV universal library)       https://github.com/FastLED/FastLED
      Fixed node-id
      Added option to request/apply last light state from gateway
     Domoticz typicals - 2015 10 10:
      - Domoticz is using HUE values internally, there might be a slight difference then using direct RGB colors.
    #include <MySensor.h>
    #include <SPI.h>
    #include <FastLED.h>
    const int stripPin = 4 ;                  // pin where 2812 LED strip is connected
    const int numPixel = 4 ;                  // set to number of pixels
    #define NODE_ID 254                       // fixed MySensors node id
    #define CHILD_ID 0                  // Child Id's
    CRGB leds[numPixel];
    char actRGBvalue[] = "000000";               // Current RGB value
    uint16_t actRGBbrightness = 0xFF ;         // Controller Brightness 
    int actRGBonoff=0;                        // OnOff flag
    MySensor gw;
    MyMessage lastColorStatusMsg(CHILD_ID,V_VAR1);
    void setup() {
      FastLED.addLeds<NEOPIXEL, stripPin >(leds, numPixel); // initialize led strip
      gw.begin(incomingMessage, AUTO, false);      // initialize MySensors
      gw.sendSketchInfo("AWI RGB Light", "1.1");
      gw.present(CHILD_ID, S_RGB_LIGHT);        // present to controller
      // Flash the "hello" color sequence: R, G, B, black. 
      //Request the last stored colors settings
      gw.request(CHILD_ID, V_VAR1);
    void loop() {
      gw.process();                       // wait for incoming messages
    void colorBars()
      SendColor2AllLEDs( CRGB::Red );   FastLED.show(); delay(500);
      SendColor2AllLEDs( CRGB::Green ); FastLED.show(); delay(500);
      SendColor2AllLEDs( CRGB::Blue );  FastLED.show(); delay(500);
      SendColor2AllLEDs( CRGB::Black ); FastLED.show(); delay(500);
    void SendColor2AllLEDs(const CRGB lcolor)
      for(int i = 0 ; i < numPixel ; i++) {
        leds[i] = lcolor;
    void SendLastColorStatus()
      String cStatus=actRGBvalue+String("&")+String(actRGBbrightness)+String("&")+String(actRGBonoff);
    String getValue(String data, char separator, int index)
     int found = 0;
      int strIndex[] = {0, -1};
      int maxIndex = data.length()-1;
      for(int i=0; i<=maxIndex && found<=index; i++){
      if(data.charAt(i)==separator || i==maxIndex){
      strIndex[0] = strIndex[1]+1;
      strIndex[1] = (i == maxIndex) ? i+1 : i;
      return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
    void incomingMessage(const MyMessage &message) {
      if (message.type == V_RGB) {            // check for RGB type
        strcpy(actRGBvalue, message.getString());    // get the payload
        SendColor2AllLEDs(strtol(actRGBvalue, NULL, 16));
      else if (message.type == V_DIMMER) {           // if DIMMER type, adjust brightness
        actRGBbrightness = map(message.getLong(), 0, 100, 0, 255);
        FastLED.setBrightness( actRGBbrightness );
      else if (message.type == V_STATUS) {           // if on/off type, toggle brightness
        actRGBonoff = message.getInt();
        FastLED.setBrightness((actRGBonoff == 1)?actRGBbrightness:0);
      else if (message.type==V_VAR1) {            // color status
        String szMessage=message.getString();
        strcpy(actRGBvalue, getValue(szMessage,'&',0).c_str());
        SendColor2AllLEDs(strtol(actRGBvalue, NULL, 16));
        FastLED.setBrightness((actRGBonoff == 1)?actRGBbrightness:0);


  • Mod

    @flopp Nice hack! 👍
    I also took apart an old Spoka once, but never managed to get the silicon back on... Aparantly you figured it out!

  • @Yveaux
    Thanks. I used alcohol to put the silicone back.
    I have add that information in the post

Log in to reply

Suggested Topics

  • 17
  • 1
  • 4
  • 2
  • 6
  • 6
  • 1
  • 7