Skip to content

Commit

Permalink
Add support for SPI OLEDs
Browse files Browse the repository at this point in the history
  • Loading branch information
antiprism committed Feb 25, 2020
1 parent 2eed63d commit 410fcba
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 80 deletions.
49 changes: 38 additions & 11 deletions ArduiPi_OLED.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ boolean ArduiPi_OLED::oled_is_spi_proto(uint8_t OLED_TYPE)
{
case OLED_ADAFRUIT_SPI_128x32:
case OLED_ADAFRUIT_SPI_128x64:
case OLED_SH1106_SPI_128x64:
return true;
break;
}
Expand Down Expand Up @@ -312,6 +313,10 @@ boolean ArduiPi_OLED::select_oled(uint8_t OLED_TYPE, int8_t i2c_addr)
_i2c_addr = SH1106_I2C_ADDRESS;
break;

case OLED_SH1106_SPI_128x64:
;
break;

// houston, we have a problem
default:
return false;
Expand Down Expand Up @@ -899,22 +904,44 @@ void ArduiPi_OLED::display(void)
{
// Setup D/C line to high to switch to data mode
bcm2835_gpio_write(dc, HIGH);

// Send all data to OLED
for ( i=0; i<oled_buff_size; i++)
if (oled_type == OLED_SH1106_SPI_128x64)
{
fastSPIwrite(*p++);
}
char buff[17] ;
uint8_t x ;
buff[0] = SSD_Data_Mode;
for (uint8_t k=0; k<8; k++)
{
sendCommand(0xB0+k);//set page addressSSD_Data_Mode;
sendCommand(0x02) ;//set lower column address
sendCommand(0x10) ;//set higher column address
bcm2835_gpio_write(dc, HIGH);

for( i=0; i<8; i++)
{
for (x=1; x<=16; x++)
buff[x] = *p++;

// I wonder why we have to do this (check datasheet)
if (oled_height == 32)
fastSPIwrite(&buff[1], 16);
}
}
}
else
{
for (uint16_t i=0; i<oled_buff_size; i++)
// Send all data to OLED
for ( i=0; i<oled_buff_size; i++)
{
fastSPIwrite(0);
fastSPIwrite(*p++);
}
}


// I wonder why we have to do this (check datasheet)
if (oled_height == 32)
{
for (uint16_t i=0; i<oled_buff_size; i++)
{
fastSPIwrite(0);
}
}
}
}
// I2C
else
Expand Down
6 changes: 4 additions & 2 deletions ArduiPi_OLED_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@
#define OLED_SEEED_I2C_128x64 4
#define OLED_SEEED_I2C_96x96 5
#define OLED_SH1106_I2C_128x64 6
#define OLED_SH1106_SPI_128x64 7

#define OLED_LAST_OLED 7 /* always last type, used in code to end array */
#define OLED_LAST_OLED 8 /* always last type, used in code to end array */

static const char * oled_type_str[] = {
"Adafruit SPI 128x32",
Expand All @@ -61,7 +62,8 @@ static const char * oled_type_str[] = {
"Adafruit I2C 128x64",
"Seeed I2C 128x64",
"Seeed I2C 96x96",
"SH1106 I2C 128x64"
"SH1106 I2C 128x64",
"SH1106 SPI 128x64"
};

// Arduino Compatible type
Expand Down
50 changes: 37 additions & 13 deletions INSTALL_MOODE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,29 @@ sudo make install
Configure your system to enable I2C or SPI, depending on how your OLED
is connected.

### I2C
I use a cheap 4 pin I2C SSH1106 display with a Raspberry Pi Zero. It is
[wired like this](https://www.14core.com/wp-content/uploads/2016/11/Raspberry-Pi-2-OLED_Screen-WIring-Diagram-Monocrome-I2C.jpg). In /boot/config.txt I
have the line `dtparam=i2c_arm=on`. In /etc/modules I have the line `i2c-dev`.
[wired like this](http://www.raspberrypirobotics.com/wp-content/uploads/2018/09/Interfacing-circuit-diagram-of-OLED-Display-with-Raspberry-Pi.png).
In /boot/config.txt I have the line `dtparam=i2c_arm=on`.
In /etc/modules I have the line `i2c-dev`.

The I2C bus speed on your system may be too slow for a reasonable screen
refresh. Set a higher bus speed by adding the
following line to /boot/config.txt (or try a higher value for a higher
screen refresh, I use 800000 with a 25 FPS screen refresh)
refresh. Set a higher bus speed by adding the following line to
/boot/config.txt, or try a higher value for a higher screen
refresh (I use 800000 with a 25 FPS screen refresh)
```
dtparam=i2c_arm_baudrate=400000
```
And then restart the Pi.
Restart the Pi after making any system configuration changes.

### SPI
I use a cheap 7 pin SPI SSH1106 display with a Raspberry Pi Zero. It is
[wired like this](http://www.raspberrypirobotics.com/wp-content/uploads/2018/03/Interfacing-OLED-Display-with-Raspberry-Pi-circuit-hardware.jpg).
In /boot/userconfig.txt (or use /boot/config.txt for Volumio versions before
2.673) I have the line `dtparam=spi=on`.

Restart the Pi after making any system configuration changes.


## Build and install mpd_oled

Expand Down Expand Up @@ -111,24 +122,38 @@ The OLED type MUST be specified with -o from the following list:
3 - Adafruit I2C 128x64,
4 - Seeed I2C 128x64,
6 - SH1106 I2C 128x64.
7 - SH1106 SPI 128x64.

E.g. the command for a generic I2C SH1106 display (OLED type 6) with
a display of 10 bars and a gap of 1 pixel between bars and a framerate
of 20Hz is
```
sudo ./mpd_oled -o 6 -b 10 -g 1 -f 20
```
For I2C OLEDs you may need to specify the I2C address, find this by running,
For I2C OLEDs (mpd_oled -o 3, 4 or 6) you may need to specify the I2C address,
find this by running,
e.g. `sudo i2cdetect -y 1` and specify the address with mpd_oled -a,
e.g. `./mpd_oled -o6 -a 3d ...`. If you have a reset pin connected, specify
the GPIO number with mpd_oled -r, e.g. `mpd_oled -o6 -r 24 ...`. (For, SPI
OLEDs, edit display.cpp to include your connection details, if this works
out I will provide options for these parameters.)
the GPIO number with mpd_oled -r, e.g. `mpd_oled -o6 -r 24 ...`.

For, SPI OLEDs (mpd_oled -o 1 or 7), you may need to specify your reset pin
GPIO number (mpd_oled -r, default 25), DC pin GPIO number (mpd_oled -D,
default 24) or CS value (mpd_oled -S, default 0).

If your display is upside down, you can rotate it 180 degrees with option '-R'.

Once the display is working, edit the file mpd_oled.service to include
your OLED type number with the mpd_oled command, and any other options.
Once the display is working, play some music and check the spectrum display
is working and is synchronised with the music. If there are no bars then the
audio copy may not have been configured correctly. If the bars seem jerky
or not synchronized with the music then reduce the values of -b and/or -f.

When you have found some suitable options then edit the file mpd_oled.service
to include your OLED type number and other options as part of the mpd_oled
command.
```
nano mpd_oled.service
```

Then run
```
sudo bash install.sh
Expand All @@ -141,4 +166,3 @@ sudo systemctl start mpd_oled
```
If you wish to change mpd_oled parameters later then edit mpd_oled.service
to include the changes and rerun install.sh.

59 changes: 39 additions & 20 deletions INSTALL_RUNEAUDIO.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,30 @@ pacman -Sy autoconf automake clang make libtool fftw alsa-lib llvm-libs glibc gc
Configure your system to enable I2C or SPI, depending on how your OLED
is connected.

### I2C
I use a cheap 4 pin I2C SSH1106 display with a Raspberry Pi Zero. It is
[wired like this](https://www.14core.com/wp-content/uploads/2016/11/Raspberry-Pi-2-OLED_Screen-WIring-Diagram-Monocrome-I2C.jpg). In /boot/config.txt I
include the line `dtparam=i2c_arm=on`. In /etc/modules-load.d/raspberrypi.conf
I include the lines `i2c-dev` and `i2c-bcm2708`.
[wired like this](http://www.raspberrypirobotics.com/wp-content/uploads/2018/09/Interfacing-circuit-diagram-of-OLED-Display-with-Raspberry-Pi.png).
In /boot/config.txt I have the line `dtparam=i2c_arm=on`.
In /etc/modules I have the line `i2c-dev`.

The I2C bus speed on your system may be too slow for a reasonable screen
refresh. Set a higher bus speed by adding the
following line to /boot/config.txt (or try a higher value for a higher
screen refresh, I use 800000 with a 25 FPS screen refresh)
refresh. Set a higher bus speed by adding the following line to
/boot/config.txt, or try a higher value for a higher screen
refresh (I use 800000 with a 25 FPS screen refresh)
```
dtparam=i2c_arm_baudrate=400000
```
Then restart the Pi.
Restart the Pi after making any system configuration changes.

### SPI
I use a cheap 7 pin SPI SSH1106 display with a Raspberry Pi Zero. It is
[wired like this](http://www.raspberrypirobotics.com/wp-content/uploads/2018/03/Interfacing-OLED-Display-with-Raspberry-Pi-circuit-hardware.jpg).
In /boot/userconfig.txt (or use /boot/config.txt for Volumio versions before
2.673) I have the line `dtparam=spi=on`.

Restart the Pi after making any system configuration changes.

### Set time zone
If, when running mpd_oled, the clock does not display the local time then
you may need
to set the system time zone. Find your timezone in the list printed by the
Expand Down Expand Up @@ -87,44 +97,53 @@ then modify /home/your-extra-mpd.conf and restart MPD,
by going to the RuneUI MPD Configuration page and clicking on
"SAVE AND APPLY" in the volume control section.

Check the mpd_oled program works correctly by running it while playing music.
Check the program works correctly by running it while playing music.
The OLED type MUST be specified with -o from the following list:
1 - Adafruit SPI 128x64,
3 - Adafruit I2C 128x64,
4 - Seeed I2C 128x64,
6 - SH1106 I2C 128x64.
7 - SH1106 SPI 128x64.

E.g. the command for a generic I2C SH1106 display (OLED type 6) with
a display of 10 bars and a gap of 1 pixel between bars and a framerate
of 15Hz is
of 20Hz is
```
./mpd_oled -o 6 -b 10 -g 1 -f 15
sudo ./mpd_oled -o 6 -b 10 -g 1 -f 20
```
For I2C OLEDs you may need to specify the I2C address, find this by running,
e.g. `i2cdetect -y 1` and specify the address with mpd_oled -a,
For I2C OLEDs (mpd_oled -o 3, 4 or 6) you may need to specify the I2C address,
find this by running,
e.g. `sudo i2cdetect -y 1` and specify the address with mpd_oled -a,
e.g. `./mpd_oled -o6 -a 3d ...`. If you have a reset pin connected, specify
the GPIO number with mpd_oled -r, e.g. `./mpd_oled -o6 -r 24 ...`. (For, SPI
OLEDs, edit display.cpp to include your connection details, if this works
out I will provide options for these parameters.)
the GPIO number with mpd_oled -r, e.g. `mpd_oled -o6 -r 24 ...`.

For, SPI OLEDs (mpd_oled -o 1 or 7), you may need to specify your reset pin
GPIO number (mpd_oled -r, default 25), DC pin GPIO number (mpd_oled -D,
default 24) or CS value (mpd_oled -S, default 0).

If your display is upside down, you can rotate it 180 degrees with option '-R'.

Once the display is working, edit the file mpd_oled.service to include
your OLED type number with the mpd_oled command, and any other options.
Once the display is working, play some music and check the spectrum display
is working and is synchronised with the music. If there are no bars then the
audio copy may not have been configured correctly. If the bars seem jerky
or not synchronized with the music then reduce the values of -b and/or -f.

When you have found some suitable options then edit the file mpd_oled.service
to include your OLED type number and other options as part of the mpd_oled
command.
```
nano mpd_oled.service
```

Then run
```
bash install.sh
sudo bash install.sh
```
This will copy the program to /usr/local/bin and add a systemd service
to run it and start it running. You can start, stop, disable, etc the
service with commands like
```
systemctl start mpd_oled
sudo systemctl start mpd_oled
```
If you wish to change mpd_oled parameters later then edit mpd_oled.service
to include the changes and rerun install.sh.

44 changes: 35 additions & 9 deletions INSTALL_VOLUMIO.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ sudo make install
Configure your system to enable I2C or SPI, depending on how your OLED
is connected.

### I2C
I use a cheap 4 pin I2C SSH1106 display with a Raspberry Pi Zero. It is
[wired like this](https://www.14core.com/wp-content/uploads/2016/11/Raspberry-Pi-2-OLED_Screen-WIring-Diagram-Monocrome-I2C.jpg). In /boot/config.txt I
have the line `dtparam=i2c_arm=on`. In /etc/modules I have the line `i2c-dev`.
[wired like this](http://www.raspberrypirobotics.com/wp-content/uploads/2018/09/Interfacing-circuit-diagram-of-OLED-Display-with-Raspberry-Pi.png).
In /boot/config.txt I have the line `dtparam=i2c_arm=on`.
In /etc/modules I have the line `i2c-dev`.

The I2C bus speed on your system may be too slow for a reasonable screen
refresh. Set a higher bus speed by adding the following line to
Expand All @@ -44,8 +46,17 @@ refresh. Set a higher bus speed by adding the following line to
```
dtparam=i2c_arm_baudrate=400000
```
Then restart the Pi.
Restart the Pi after making any system configuration changes.

### SPI
I use a cheap 7 pin SPI SSH1106 display with a Raspberry Pi Zero. It is
[wired like this](http://www.raspberrypirobotics.com/wp-content/uploads/2018/03/Interfacing-OLED-Display-with-Raspberry-Pi-circuit-hardware.jpg).
In /boot/userconfig.txt (or use /boot/config.txt for Volumio versions before
2.673) I have the line `dtparam=spi=on`.

Restart the Pi after making any system configuration changes.

### Configure copy of audio
The MPD audio output needs to be copied to a named pipe, where Cava can
read it and calculate the spectrum. This should be configured in /etc/mpd.conf,
but changes to this file will be overwritten by Volumio. Instead, edit the
Expand All @@ -66,6 +77,7 @@ After editing the file it is important to force Volumio to regenerate
mpd.conf and restart MPD. Do this by going to the Web UI PLAYBACK OPTIONS
and clicking on the Audio Outputs save button.

### Set time zone
If the mpd_oled clock does not display the local time then you may need
to set the system time zone. The following command will run a console
based application where you can specify your location
Expand Down Expand Up @@ -94,24 +106,38 @@ The OLED type MUST be specified with -o from the following list:
3 - Adafruit I2C 128x64,
4 - Seeed I2C 128x64,
6 - SH1106 I2C 128x64.
7 - SH1106 SPI 128x64.

E.g. the command for a generic I2C SH1106 display (OLED type 6) with
a display of 10 bars and a gap of 1 pixel between bars and a framerate
of 20Hz is
```
sudo ./mpd_oled -o 6 -b 10 -g 1 -f 20
```
For I2C OLEDs you may need to specify the I2C address, find this by running,
For I2C OLEDs (mpd_oled -o 3, 4 or 6) you may need to specify the I2C address,
find this by running,
e.g. `sudo i2cdetect -y 1` and specify the address with mpd_oled -a,
e.g. `./mpd_oled -o6 -a 3d ...`. If you have a reset pin connected, specify
the GPIO number with mpd_oled -r, e.g. `mpd_oled -o6 -r 24 ...`. (For, SPI
OLEDs, edit display.cpp to include your connection details, if this works
out I will provide options for these parameters.)
the GPIO number with mpd_oled -r, e.g. `mpd_oled -o6 -r 24 ...`.

For, SPI OLEDs (mpd_oled -o 1 or 7), you may need to specify your reset pin
GPIO number (mpd_oled -r, default 25), DC pin GPIO number (mpd_oled -D,
default 24) or CS value (mpd_oled -S, default 0).

If your display is upside down, you can rotate it 180 degrees with option '-R'.

Once the display is working, edit the file mpd_oled.service to include
your OLED type number with the mpd_oled command, and any other options.
Once the display is working, play some music and check the spectrum display
is working and is synchronised with the music. If there are no bars then the
audio copy may not have been configured correctly. If the bars seem jerky
or not synchronized with the music then reduce the values of -b and/or -f.

When you have found some suitable options then edit the file mpd_oled.service
to include your OLED type number and other options as part of the mpd_oled
command.
```
nano mpd_oled.service
```

Then run
```
sudo bash install.sh
Expand Down

0 comments on commit 410fcba

Please sign in to comment.