Full Code of frumperino/FrekvensPanel for AI

master 07ae202ee24b cached
10 files
20.8 KB
7.9k tokens
6 symbols
1 requests
Download .txt
Repository: frumperino/FrekvensPanel
Branch: master
Commit: 07ae202ee24b
Files: 10
Total size: 20.8 KB

Directory structure:
gitextract_c8sobvkw/

├── FrekvensPanel/
│   ├── FrekvensPanel.cpp
│   ├── FrekvensPanel.h
│   ├── examples/
│   │   ├── buttons/
│   │   │   ├── button.h
│   │   │   └── buttons.ino
│   │   ├── pika/
│   │   │   ├── bm_pika.h
│   │   │   └── pika.ino
│   │   └── sparkles/
│   │       └── sparkles.ino
│   ├── library.properties
│   └── readme.md
└── readme.md

================================================
FILE CONTENTS
================================================

================================================
FILE: FrekvensPanel/FrekvensPanel.cpp
================================================
// By /u/frumperino
// goodwires.org

#include "FrekvensPanel.h"

void init(int p_latch, int p_clock, int p_data, int p_enable);

FrekvensPanel::FrekvensPanel(int p_latch, int p_clock, int p_data, int bitDepth,
                             int numPanels) : Adafruit_GFX(16, numPanels * 16)
{
    init(p_latch, p_clock, p_data, bitDepth, numPanels);
}

FrekvensPanel::FrekvensPanel(int p_latch, int p_clock, int p_data) :
FrekvensPanel(p_latch, p_clock, p_data, 0, 1) { }

void FrekvensPanel::init(int p_latch, int p_clock, int p_data, int bitDepth, int numPanels)
{
    _pLatch = p_latch;
    _pClock = p_clock;
    _pData = p_data;
    pinMode(_pLatch, OUTPUT);
    pinMode(_pClock, OUTPUT);
    pinMode(_pData, OUTPUT);
    _bitDepth = bitDepth;
    _numPages = (1 << bitDepth);
    _pageMask = _numPages - 1;
    _numPanels = numPanels;
    _pageStride = 16 * numPanels;
    _numWords = _numPages * _pageStride;
    _numPixels = 16 * 16 * numPanels;
    _addressMask = _numPixels-1;
    _width = 16;
    _height = 16 * _numPanels;
    buf = (unsigned short*) malloc(_numWords * sizeof(unsigned short));
}

void FrekvensPanel::clear()
{
    for (int i=0;i<_numWords;i++)
    {
        buf[i] = 0;
    }
}

void FrekvensPanel::writeDeepPixel(unsigned short x, unsigned short y, unsigned short value)
{
    if (x > 7) { y += 0x10; x &= 0x07; }
    unsigned int address = (x + (y << 3)) & _addressMask;
    unsigned short ba = address >> 4;
    unsigned short br = address & 0x0F;
    unsigned short ms = (1 << br);
    unsigned short mc = 0xFFFF ^ ms;
    unsigned short* wp = &buf[ba];
    unsigned short ofs = (x+y) & _pageMask;
    for (unsigned int i=0;i<_numPages;i++)
    {
        ofs++;
        ofs &= _pageMask;
        char b = ((value >> ofs) & 0x01);
        if (b)
        {
            *wp |= ms;
        }
        else
        {
            *wp &= mc;
        }
        wp+=_pageStride;
    }
}

void FrekvensPanel::scan()
{
    if (_numPages == 1)
    {
        // single bit plane
        unsigned short* p = &buf[0];
        for (int i=0;i<_pageStride;i++)
        {
            unsigned short w = *p++;
            for (int j=0;j<16;j++)
            {
                digitalWrite(_pData, w & 0x01);
                w >>= 1;
                digitalWrite(_pClock, HIGH);
                delayMicroseconds(1);
                digitalWrite(_pClock, LOW);
            }
        }
        digitalWrite(_pLatch,HIGH);
        delayMicroseconds(1);
        digitalWrite(_pLatch,LOW);
    }
    else
    {
        // multiple bit planes
        unsigned short* p = &buf[_pageStride * _activePage];
        for (int i=0;i<_pageStride;i++)
        {
            unsigned short w = *p++;
            for (int j=0;j<16;j++)
            {
                digitalWrite(_pData, w & 0x01);
                w >>= 1;
                digitalWrite(_pClock, HIGH);
                delayMicroseconds(1);
                digitalWrite(_pClock, LOW);
            }
        }
        digitalWrite(_pLatch,HIGH);
        delayMicroseconds(1);
        digitalWrite(_pLatch,LOW);
        _activePage++;
        _activePage %= _numPages;
    }
}

unsigned short FrekvensPanel::width()
{
    return this->_width;
}

unsigned short FrekvensPanel::height()
{
    return this->_height;
}

boolean FrekvensPanel::getPixel(int16_t x, int16_t y)
{
    if (x > 7) { y += 0x10; x &= 0x07; }
    unsigned short address = (x + (y << 3)) & _addressMask;
    unsigned short ba = address >> 4;
    unsigned short br = address & 0x0F;
    unsigned short* wp = &buf[ba];
    return ((*wp) >> br) & 0x01;
}

void FrekvensPanel::drawPixel(int16_t x, int16_t y, uint16_t color)
{
    if ((x >= 0) && (y >= 0) && (x < _width) && ( y < _height))
    {
        if (x > 7) { y += 0x10; x &= 0x07; }
        unsigned short address = (x + (y << 3)) & _addressMask;
        unsigned short ba = address >> 4;
        unsigned short br = address & 0x0F;
        unsigned short ms = (1 << br);
        unsigned short* wp = &buf[ba];
        if (color & 0x01)
        {
            *wp |= ms;
        }
        else
        {
            *wp &= (0xFFFF ^ ms);
        }
    }
}

void FrekvensPanel::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
{
    for (int i=0;i<h;i++)
    {
        drawPixel(x,y+i,color);
    }

}

void FrekvensPanel::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)
{
    for (int i=0;i<w;i++)
    {
        drawPixel(x+i,y,color);
    }
}

void FrekvensPanel::fillScreen(uint16_t color)
{
    for (int i=0;i<_numPages;i++)
    {
        unsigned short w = color & 0x01 ? 0xFFFF : 0x0000;
        color >>= 1;
        unsigned short* p = &buf[i * _pageStride];
        for (int j=0;j<_pageStride;j++)
        {
            *p++ = w;
        }
    }
}







================================================
FILE: FrekvensPanel/FrekvensPanel.h
================================================
// by /u/frumperino
// goodwires.org

#ifndef __FREKVENSPANEL_H
#define __FREKVENSPANEL_H

#include <Arduino.h>
#include <Adafruit_GFX.h>

class FrekvensPanel : public Adafruit_GFX
{
private:
    unsigned short _numPanels : 4;
    unsigned short _numPages : 4;
    unsigned short _activePage : 4;
    unsigned short _bitDepth : 4;
    unsigned short _pLatch;
    unsigned short _pClock;
    unsigned short _pData;
    unsigned short* buf;
    unsigned short _pageMask;
    unsigned short _addressMask;
    unsigned short _numWords;
    unsigned short _pageStride;
    unsigned short _numPixels;
    unsigned short _width;
    unsigned short _height;

public:
    FrekvensPanel(int p_latch, int p_clock, int p_data, int bitDepth,
                  int numPanels);
    FrekvensPanel(int p_latch, int p_clock, int p_data);

    void init(int p_latch, int p_clock, int p_data, int bitDepth, int numPanels);
    void clear();
    void scan();
    void writeDeepPixel(unsigned short x, unsigned short y, unsigned short value);

    boolean getPixel(int16_t x, int16_t y);

    unsigned short width();
    unsigned short height();

    void drawPixel(int16_t x, int16_t y, uint16_t color) override;
    void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) override;
    void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) override;
    void fillScreen(uint16_t color) override;

private:

};


#endif //__FREKVENSPANEL_H


================================================
FILE: FrekvensPanel/examples/buttons/button.h
================================================
//
// Created by /u/frumperino
//

#include <Arduino.h>

#ifndef __simplebutton_h
#define __simplebutton_h

typedef void (*ButtonEH) (int, int); // id, state

class SimpleButton
{
private:
    unsigned short pin      : 8;
    unsigned short state    : 1;
    unsigned short invert   : 1;
    unsigned short changing : 1;
    unsigned short attached : 1;
    char id;
    ButtonEH handler = nullptr;
    unsigned short debounceMS;
    unsigned long tChange = 0;
public:
    SimpleButton(char id, char pin, char invert, unsigned short debounceMS)
    {
        this->id = id;
        this->invert = invert;
        this->pin = pin;
        this->changing = false;
        this->debounceMS = debounceMS;
        this->state = digitalRead(pin);
        this->attached = false;
    }

    void attachHandler(ButtonEH handler)
    {
        this->handler = handler;
        this->attached = true;
    }

    char getState()
    {
        return this->state;
    }

    void scan()
    {
        char newState = digitalRead(pin);
        if (newState == state)
        {
          changing = false;          
        }
        else
        {
            unsigned long tNow = millis();
            if (!changing)
            {
                changing = true;
                tChange = tNow;
            }
            else
            {
                unsigned long tD = tNow - tChange;
                if (tD >= debounceMS)
                {
                    state = newState;
                    changing = false;
                    if (attached)
                    {
                        handler(id, state ^ invert);
                    }
                }
            }
        }
    }

};

#endif //__simplebutton_h


================================================
FILE: FrekvensPanel/examples/buttons/buttons.ino
================================================
#include <FrekvensPanel.h>
// see readme.md for wiring instructions

#include "button.h"

#define buttonCOM_VCC // comment out this line if button COM is wired to GND.  

#define p_ena 5 
#define p_data 6
#define p_clock 9
#define p_latch 10

#define p_btn1 14 // A0 (Adafruit Feather M0) - RED button (black wire)
#define p_btn2 15 // A1 (Adafruit Feather M0) - YELLOW button (white wire)

FrekvensPanel panel(p_latch, p_clock, p_data);

char activeProgram = 1;
char activeBrightMode = 1;

#ifdef buttonCOM_VCC
// the red wire (COM) for the buttons is connected to (MCU board) VCC, 
// so the button signal is positive and the button input pins must be set to INPUT_PULLDOWN
SimpleButton button1(1,p_btn1,0,20);
SimpleButton button2(2,p_btn2,0,20);
#else
// the red wire (COM) for the buttons is connected to GND, so the button signal is inverted
SimpleButton button1(1,p_btn1,1,20);
SimpleButton button2(2,p_btn2,1,20);
#endif

void setBrightMode(int brightMode)
{
  activeBrightMode = brightMode % 4;
  switch(activeBrightMode)
  {
    case 0: { pinMode(p_ena, OUTPUT); digitalWrite(p_ena, 1); } break; // off
    case 1: analogWrite(p_ena, 254); break; // very dim
    case 2: analogWrite(p_ena, 240); break; // dim
    case 3: { pinMode(p_ena, OUTPUT); digitalWrite(p_ena, 0); } break; // on 100%
  }
}

void setProgram(int program)
{
  activeProgram = (program % 3);
}

void buttonHandler(int id, int state)
{
  if (state) // button pressed
  {
    switch(id)
    {
      case 1: setBrightMode(activeBrightMode+1); break;
      case 2: setProgram(activeProgram+1); break;
    }
  }  
}

void program0()
{
  for (int i=0;i<20;i++)
  {
    panel.drawPixel(random(16),random(16),random(10) == 0);
  }
}

int p1_i = 0;
void program1()
{
  float pi23 = PI*2/3;
  float p = 0.02 * p1_i++;
  int x0 = 7.98 + 7.98 * cos(p);
  int y0 = 7.98 + 7.98 * sin(p);
  p += pi23;
  int x1 = 7.98 + 7.98 * cos(p);
  int y1 = 7.98 + 7.98 * sin(p);
  p += pi23;
  int x2 = 7.98 + 7.98 * cos(p);
  int y2 = 7.98 + 7.98 * sin(p);
  panel.clear();
  panel.drawLine(x0,y0,x1,y1,1);  
  panel.drawLine(x1,y1,x2,y2,1);  
  panel.drawLine(x2,y2,x0,y0,1);  
}


void program2()
{
  int x = random(16);
  int y = random(16);
  panel.drawRect(x,y,random(16-x),random(16-y),random(6)==0);
}

void setup() 
{
#ifdef buttonCOM_VCC
  pinMode(p_btn1, INPUT_PULLDOWN); 
  pinMode(p_btn2, INPUT_PULLDOWN); 
#else
  pinMode(p_btn1, INPUT_PULLUP); 
  pinMode(p_btn2, INPUT_PULLUP); 
#endif
  panel.clear();
  pinMode(p_ena, OUTPUT); 
  analogWrite(p_ena, 0); // full brightness
  button1.attachHandler(buttonHandler);
  button2.attachHandler(buttonHandler);
  panel.scan();
}

void loop() 
{
  switch(activeProgram)
  {
    case 0: program0(); break;
    case 1: program1(); break;
    case 2: program2(); break;
  }
  panel.scan();
  button1.scan();
  button2.scan();
  delay(2);
}


================================================
FILE: FrekvensPanel/examples/pika/bm_pika.h
================================================
//
// Created by /u/fumperino on 2020-02-15.
//

#ifndef __bm_pika_h
#define __bm_pika_h

static const unsigned short bm_pika_width = 56;
static const unsigned short bm_pika_height = 56;
static const unsigned char bm_pika[] =
{
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // row 00
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // row 01
        0xFF, 0xBF, 0x60, 0xDF, 0xBF, 0xC7, 0xFF,  // row 02
        0xFF, 0xBF, 0x6F, 0xDF, 0xBF, 0xB9, 0xFF,  // row 03
        0xFF, 0xBF, 0x6F, 0xDF, 0xBF, 0x7D, 0xFF,  // row 04
        0xFF, 0xBF, 0x6F, 0xDF, 0xBE, 0xFE, 0xFF,  // row 05
        0xFF, 0xBF, 0x6F, 0xDF, 0xBE, 0xFE, 0xFF,  // row 06
        0xFF, 0x80, 0x60, 0xDF, 0xBE, 0xFE, 0xFF,  // row 07
        0xFF, 0xBF, 0x6F, 0xDF, 0xBE, 0xFE, 0xFF,  // row 08
        0xFF, 0xBF, 0x6F, 0xDF, 0xBE, 0xFE, 0xFF,  // row 09
        0xFF, 0xBF, 0x6F, 0xDF, 0xBF, 0x7D, 0xFF,  // row 10
        0xFF, 0xBF, 0x6F, 0xDF, 0xBF, 0x3B, 0xFF,  // row 11
        0xFF, 0xBF, 0x60, 0x40, 0x81, 0xC7, 0xFF,  // row 12
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // row 13
        0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,  // row 14
        0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFF,  // row 15
        0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFF,  // row 16
        0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF,  // row 17
        0xF8, 0x7F, 0xF8, 0xBF, 0xFF, 0x83, 0xFF,  // row 18
        0xF7, 0xBF, 0xFB, 0xBF, 0xFC, 0x43, 0xFF,  // row 19
        0xEF, 0xDF, 0xF3, 0xBF, 0xF3, 0xC7, 0xFF,  // row 20
        0xEF, 0xDF, 0xF7, 0xC1, 0xCF, 0xCF, 0xFF,  // row 21
        0xEF, 0xDF, 0xF7, 0x3E, 0x3F, 0x9F, 0xFF,  // row 22
        0xE0, 0x1F, 0xF5, 0xFF, 0xFF, 0xBE, 0x7F,  // row 23
        0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x7D, 0xBF,  // row 24
        0xFF, 0xDF, 0xEF, 0xFF, 0xFE, 0xFD, 0xCF,  // row 25
        0xFF, 0xDF, 0xE7, 0xF9, 0xFD, 0xFB, 0xF7,  // row 26
        0xFF, 0xDF, 0xD7, 0xF4, 0xF3, 0xFB, 0xFB,  // row 27
        0xE0, 0x1F, 0xC7, 0xF0, 0xFB, 0xF7, 0xFB,  // row 28
        0xFF, 0xFF, 0xAD, 0xF9, 0xFB, 0xF7, 0xFB,  // row 29
        0xF1, 0x9F, 0xBF, 0xFF, 0x3D, 0xEF, 0xF7,  // row 30
        0xEE, 0x7F, 0x9A, 0x6E, 0x1D, 0xEF, 0xEF,  // row 31
        0xEE, 0xFF, 0x9C, 0x1E, 0x1E, 0xDF, 0xDF,  // row 32
        0xEE, 0xFF, 0x9E, 0x3F, 0x1E, 0xDF, 0xBF,  // row 33
        0xE0, 0x1E, 0x5E, 0x7F, 0xAE, 0x5F, 0x7F,  // row 34
        0xFF, 0xFD, 0xEF, 0xFE, 0x74, 0x6F, 0x3F,  // row 35
        0xFF, 0xFD, 0xF7, 0xFF, 0xF6, 0x77, 0xDF,  // row 36
        0xF8, 0x7E, 0xFF, 0xFF, 0xEF, 0xB7, 0x9F,  // row 37
        0xF7, 0xBF, 0x7F, 0xFF, 0xFF, 0xAF, 0x7F,  // row 38
        0xEF, 0xDF, 0x9F, 0xFF, 0x8E, 0x9C, 0xFF,  // row 39
        0xEF, 0xDF, 0xEF, 0xFD, 0x74, 0x2D, 0xFF,  // row 40
        0xEF, 0xDF, 0xE7, 0xFA, 0xBE, 0x0E, 0xFF,  // row 41
        0xF7, 0xBF, 0xF7, 0xFB, 0xBF, 0x89, 0xFF,  // row 42
        0xF8, 0x7F, 0xF7, 0xFB, 0xDF, 0x47, 0xFF,  // row 43
        0xE7, 0xFF, 0xF7, 0xFD, 0xDF, 0x1F, 0xFF,  // row 44
        0xF8, 0x7F, 0xFB, 0xFD, 0xDE, 0x7F, 0xFF,  // row 45
        0xFF, 0x9F, 0xFB, 0xFD, 0xBD, 0xFF, 0xFF,  // row 46
        0xF8, 0x3F, 0xFD, 0xFE, 0x7B, 0xFF, 0xFF,  // row 47
        0xE7, 0xFF, 0xFE, 0x7F, 0xC7, 0xFF, 0xFF,  // row 48
        0xF8, 0x7F, 0xFF, 0x9F, 0x3F, 0xFF, 0xFF,  // row 49
        0xFF, 0x9F, 0xFF, 0xE4, 0x7F, 0xFF, 0xFF,  // row 50
        0xF8, 0x3F, 0xFF, 0xF7, 0x7F, 0xFF, 0xFF,  // row 51
        0xE7, 0xFF, 0xFF, 0xF5, 0x7F, 0xFF, 0xFF,  // row 52
        0xFF, 0xFF, 0xFF, 0xFA, 0xFF, 0xFF, 0xFF,  // row 53
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // row 54
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // row 55
};

#endif // __bm_pika_h


================================================
FILE: FrekvensPanel/examples/pika/pika.ino
================================================
#include <FrekvensPanel.h>
// see readme.md for wiring instructions

#include "bm_pika.h"

#define p_ena 5 
#define p_data 6
#define p_clock 9
#define p_latch 10

#define p_btn1 14 // A0 (Adafruit Feather M0) - RED button (black wire)
#define p_btn2 15 // A1 (Adafruit Feather M0) - YELLOW button (white wire)

FrekvensPanel panel(p_latch, p_clock, p_data);

int i = 0;

void setup() 
{
  panel.clear();
  panel.scan();
  pinMode(p_ena, OUTPUT); 
  analogWrite(p_ena, 0); // full brightness
}

void loop() 
{
  panel.fillScreen(1);
  int pw = panel.width();
  int ph = panel.height();
  int bw = bm_pika_width;
  int bh = bm_pika_height;

  float p = (0.002 * i++);
  float bw2 = (float) (bw - pw) / 2;
  float bh2 = (float) (bh - ph) / 2;
  int x = (int) (bw2 + bw2 * cos(p * 3)) - bw + pw;
  int y = (int) (bh2 + bh2 * sin(p * 4)) - bh + ph;
  panel.drawBitmap(x,y,&bm_pika[0],bw,bh,0);
  panel.scan();
}


================================================
FILE: FrekvensPanel/examples/sparkles/sparkles.ino
================================================
#include <FrekvensPanel.h>
// see readme.md for wiring instructions

#define p_ena 5 
#define p_data 6
#define p_clock 9
#define p_latch 10

#define p_btn1 14 // A0 (Adafruit Feather M0) - RED button (black wire)
#define p_btn2 15 // A1 (Adafruit Feather M0) - YELLOW button (white wire)

FrekvensPanel panel(p_latch, p_clock, p_data);

void setup() 
{
  panel.clear();
  panel.scan();
  pinMode(p_ena, OUTPUT); 
  analogWrite(p_ena, 0); // full brightness
}

void loop() 
{
  for (int i=0;i<20;i++)
  {
    panel.drawPixel(random(16),random(16),random(10) == 0);
  }
  panel.scan(); // refreshes display
  delay(5);
}


================================================
FILE: FrekvensPanel/library.properties
================================================
name=FrekvensPanel
version=0.0.1
author=/u/frumperino
maintainer=/u/frumperino
sentence=Frekvens LED panel driver
paragraph=Use an Arduino to drive the IKEA Frekvens LED panel. 
category=Display
includes=FrekvensPanel.h
architectures=*
url=https://github.com/frumperino/FrekvensPanel

================================================
FILE: FrekvensPanel/readme.md
================================================
This is a first rough cut of an Arduino library for the IKEA FREKVENS LED panels developed jointly with Teenage Engineering.

Contributions welcome.

Arduino requirements: Must be type with 3.3V logic levels. If you want to try hooking this up through 8-bit 5V AVR antiques like an Arduino Uno, then you must use level shifters. 

Recommendation: Use Teensy 3+, Adafruit Feather M0 or Sparkfun SAMD21 mini breakouts. Should also work with 32U4 based boards as well, so
long as they're 3.3V. Haven't tried with ESP8266 yet. 

Library dependencies:
- Adafruit GFX library must be installed.

Soldering instructions:
- Open & disassemble the LED cube. 

- Extract the mainboard.

- Desolder the original controller daughterboard (green color).
  * Use flux and solder wick. 

- Attach wires to the six solder points.
  * The outermost solder points are marked VCC and GND. 
  * Let GND be (1) and VCC be (6). The middle four are as follows:
  * (2) LATCH - connect to a digital output pin. 
  * (3) CLOCK - connect to a digital output pin.
  * (4) DATA - connect to a digital output pin.
  * (5) !ENABLE. This one is optional. 
        If you DON'T need to be able to control brightness
        of the display, then just solder a wire from this pin
        to GND. 
        If you DO want to control brightness, then connect this
        pin to a PWM ("analog") output pin on your Arduino.

  * Solder the GND wire to a GND pin on the Arduino.

  * Leave the VCC wire unconnected until you're done programming
  * The VCC wire has 4 volts on it coming from the isolated power
  * supply of the Frekvens cube.
  * While programming, the Arduino should be powered through USB.
  * After programming, disconnect USB cable and attach VCC wire
  * from Frekvens panel to battery input or "USB" voltage pin on
  * the Arduino. The Frekvens panel will now supply the Arduino
  * board voltages.

- Optionally - hook up the red and yellow buttons on the back.
  * RED wire is common so connect this to GND or VCC of the
  * Arduino. BLACK wire is RED button, WHITE wire is YELLOW button. 

- Put the whole thing back together.

- To use the library, add #include "Frekvenspanel.h" statement, and instantiate a FrekvensPanel object. See examples.

- Library has several un-documented experimental modes, including
  multiple bit planes (intensity dithering) and support for daisy-
  chaining several modules. Needs more work. At the moment the daisy-
  chain is mapped vertically which seems wrong. 

- Happy hacking



================================================
FILE: readme.md
================================================
This is a first rough cut of an Arduino library for the IKEA FREKVENS LED panels developed jointly with Teenage Engineering.

Contributions welcome.

Arduino requirements: Must be type with 3.3V logic levels. If you want to try hooking this up through 8-bit 5V AVR antiques like an Arduino Uno, then you must use level shifters. 

Recommendation: Use Teensy 3+, Adafruit Feather M0 or Sparkfun SAMD21 mini breakouts. Should also work with 32U4 based boards as well, so
long as they're 3.3V. Haven't tried with ESP8266 yet. 

Library dependencies:
- Adafruit GFX library must be installed.

Soldering instructions:
- Open & disassemble the LED cube. 

- Extract the mainboard.

- Desolder the original controller daughterboard (green color).
  * Use flux and solder wick. 

- Attach wires to the six solder points.
  * The outermost solder points are marked VCC and GND. 
  * Let GND be (1) and VCC be (6). The middle four are as follows:
  * (2) LATCH - connect to a digital output pin. 
  * (3) CLOCK - connect to a digital output pin.
  * (4) DATA - connect to a digital output pin.
  * (5) !ENABLE. This one is optional. 
        If you DON'T need to be able to control brightness
        of the display, then just solder a wire from this pin
        to GND. 
        If you DO want to control brightness, then connect this
        pin to a PWM ("analog") output pin on your Arduino.

  * Solder the GND wire to a GND pin on the Arduino.

  * Leave the VCC wire unconnected until you're done programming
  * The VCC wire has 4 volts on it coming from the isolated power
  * supply of the Frekvens cube.
  * While programming, the Arduino should be powered through USB.
  * After programming, disconnect USB cable and attach VCC wire
  * from Frekvens panel to battery input or "USB" voltage pin on
  * the Arduino. The Frekvens panel will now supply the Arduino
  * board voltages.

- Optionally - hook up the red and yellow buttons on the back.
  * RED wire is common so connect this to GND or VCC of the
  * Arduino. BLACK wire is RED button, WHITE wire is YELLOW button. 

- Put the whole thing back together.

- To use the library, add #include "Frekvenspanel.h" statement, and instantiate a FrekvensPanel object. See examples.

- Library has several un-documented experimental modes, including
  multiple bit planes (intensity dithering) and support for daisy-
  chaining several modules. Needs more work. At the moment the daisy-
  chain is mapped vertically which seems wrong. 

- Happy hacking

Download .txt
gitextract_c8sobvkw/

├── FrekvensPanel/
│   ├── FrekvensPanel.cpp
│   ├── FrekvensPanel.h
│   ├── examples/
│   │   ├── buttons/
│   │   │   ├── button.h
│   │   │   └── buttons.ino
│   │   ├── pika/
│   │   │   ├── bm_pika.h
│   │   │   └── pika.ino
│   │   └── sparkles/
│   │       └── sparkles.ino
│   ├── library.properties
│   └── readme.md
└── readme.md
Download .txt
SYMBOL INDEX (6 symbols across 3 files)

FILE: FrekvensPanel/FrekvensPanel.cpp
  function boolean (line 129) | boolean FrekvensPanel::getPixel(int16_t x, int16_t y)

FILE: FrekvensPanel/FrekvensPanel.h
  function class (line 10) | class FrekvensPanel : public Adafruit_GFX

FILE: FrekvensPanel/examples/buttons/button.h
  function class (line 12) | class SimpleButton
  function attachHandler (line 36) | void attachHandler(ButtonEH handler)
  function getState (line 42) | char getState()
  function scan (line 47) | void scan()
Condensed preview — 10 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (23K chars).
[
  {
    "path": "FrekvensPanel/FrekvensPanel.cpp",
    "chars": 4770,
    "preview": "// By /u/frumperino\n// goodwires.org\n\n#include \"FrekvensPanel.h\"\n\nvoid init(int p_latch, int p_clock, int p_data, int p_"
  },
  {
    "path": "FrekvensPanel/FrekvensPanel.h",
    "chars": 1445,
    "preview": "// by /u/frumperino\n// goodwires.org\n\n#ifndef __FREKVENSPANEL_H\n#define __FREKVENSPANEL_H\n\n#include <Arduino.h>\n#include"
  },
  {
    "path": "FrekvensPanel/examples/buttons/button.h",
    "chars": 1722,
    "preview": "//\n// Created by /u/frumperino\n//\n\n#include <Arduino.h>\n\n#ifndef __simplebutton_h\n#define __simplebutton_h\n\ntypedef void"
  },
  {
    "path": "FrekvensPanel/examples/buttons/buttons.ino",
    "chars": 2849,
    "preview": "#include <FrekvensPanel.h>\n// see readme.md for wiring instructions\n\n#include \"button.h\"\n\n#define buttonCOM_VCC // comme"
  },
  {
    "path": "FrekvensPanel/examples/pika/bm_pika.h",
    "chars": 3670,
    "preview": "//\n// Created by /u/fumperino on 2020-02-15.\n//\n\n#ifndef __bm_pika_h\n#define __bm_pika_h\n\nstatic const unsigned short bm"
  },
  {
    "path": "FrekvensPanel/examples/pika/pika.ino",
    "chars": 907,
    "preview": "#include <FrekvensPanel.h>\n// see readme.md for wiring instructions\n\n#include \"bm_pika.h\"\n\n#define p_ena 5 \n#define p_da"
  },
  {
    "path": "FrekvensPanel/examples/sparkles/sparkles.ino",
    "chars": 619,
    "preview": "#include <FrekvensPanel.h>\n// see readme.md for wiring instructions\n\n#define p_ena 5 \n#define p_data 6\n#define p_clock 9"
  },
  {
    "path": "FrekvensPanel/library.properties",
    "chars": 283,
    "preview": "name=FrekvensPanel\nversion=0.0.1\nauthor=/u/frumperino\nmaintainer=/u/frumperino\nsentence=Frekvens LED panel driver\nparagr"
  },
  {
    "path": "FrekvensPanel/readme.md",
    "chars": 2506,
    "preview": "This is a first rough cut of an Arduino library for the IKEA FREKVENS LED panels developed jointly with Teenage Engineer"
  },
  {
    "path": "readme.md",
    "chars": 2506,
    "preview": "This is a first rough cut of an Arduino library for the IKEA FREKVENS LED panels developed jointly with Teenage Engineer"
  }
]

About this extraction

This page contains the full source code of the frumperino/FrekvensPanel GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 10 files (20.8 KB), approximately 7.9k tokens, and a symbol index with 6 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!