oled-control 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/oled-control/extconf.rb +5 -0
- data/ext/oled-control/main.c +74 -0
- data/ext/oled-control/oled-control-gem.c +101 -0
- data/ext/oled-control/oled-control.c +136 -0
- data/ext/oled-control/oled-control.h +37 -0
- data/lib/oled-control/oled.rb +83 -0
- metadata +50 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4c496a83d860309cdefd939cff54744d546ee3a9
|
4
|
+
data.tar.gz: 20260794cf74b80a183303d7ea79cf467082e86c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5f99bf7fb85a8edb3badce29b6885ab3be3a96d52577e08207a39d8908246571b0b84c20c96d23d4c70579ad8e99636bf5bc331fb0661cd6240a04673b9919a2
|
7
|
+
data.tar.gz: e802e762c16ac8723e868a389e43874829ee05d8d537d5de1bd4fe540b7894495b420273481c1ba08ef6c61cc5cb01f9e4ad55f116918abbba966336db67146d
|
@@ -0,0 +1,74 @@
|
|
1
|
+
//
|
2
|
+
// Created by sokkalf on 3/6/16.
|
3
|
+
//
|
4
|
+
#include "oled-control.h"
|
5
|
+
|
6
|
+
void test_display() {
|
7
|
+
set_cursor_position(2, 1);
|
8
|
+
i2c_write_bytes(DATA, "In A.D. 2101");
|
9
|
+
set_cursor_position(1, 2);
|
10
|
+
i2c_write_bytes(DATA, "War was beginning.");
|
11
|
+
sleep(5);
|
12
|
+
clear_display();
|
13
|
+
set_cursor_position(2, 1);
|
14
|
+
i2c_write_bytes(DATA, "Captain:");
|
15
|
+
set_cursor_position(4, 2);
|
16
|
+
i2c_write_bytes(DATA, "What happen?");
|
17
|
+
sleep(2);
|
18
|
+
clear_display();
|
19
|
+
set_cursor_position(2, 1);
|
20
|
+
i2c_write_bytes(DATA, "Mechanic:");
|
21
|
+
set_cursor_position(0, 2);
|
22
|
+
i2c_write_bytes(DATA, "Somebody set up us");
|
23
|
+
set_cursor_position(0, 3);
|
24
|
+
i2c_write_bytes(DATA, "the bomb");
|
25
|
+
sleep(2);
|
26
|
+
clear_display();
|
27
|
+
set_cursor_position(2, 1);
|
28
|
+
i2c_write_bytes(DATA, "Operator:");
|
29
|
+
set_cursor_position(0, 2);
|
30
|
+
i2c_write_bytes(DATA, "We get signal.");
|
31
|
+
sleep(2);
|
32
|
+
clear_display();
|
33
|
+
set_cursor_position(2, 1);
|
34
|
+
i2c_write_bytes(DATA, "Captain:");
|
35
|
+
set_cursor_position(0, 2);
|
36
|
+
i2c_write_bytes(DATA, "WHAT !");
|
37
|
+
sleep(2);
|
38
|
+
clear_display();
|
39
|
+
set_cursor_position(2, 1);
|
40
|
+
i2c_write_bytes(DATA, "Operator:");
|
41
|
+
set_cursor_position(1, 2);
|
42
|
+
i2c_write_bytes(DATA, "Main screen");
|
43
|
+
set_cursor_position(1, 3);
|
44
|
+
i2c_write_bytes(DATA, "turn on.");
|
45
|
+
sleep(2);
|
46
|
+
clear_display();
|
47
|
+
set_cursor_position(2, 1);
|
48
|
+
i2c_write_bytes(DATA, "Captain:");
|
49
|
+
set_cursor_position(0, 2);
|
50
|
+
i2c_write_bytes(DATA, "It's you !!");
|
51
|
+
sleep(2);
|
52
|
+
clear_display();
|
53
|
+
set_cursor_position(2, 1);
|
54
|
+
i2c_write_bytes(DATA, "Cats:");
|
55
|
+
set_cursor_position(0, 2);
|
56
|
+
i2c_write_bytes(DATA, "How are you");
|
57
|
+
set_cursor_position(1, 3);
|
58
|
+
i2c_write_bytes(DATA, "gentlemen !!");
|
59
|
+
sleep(2);
|
60
|
+
clear_display();
|
61
|
+
set_cursor_position(2, 1);
|
62
|
+
i2c_write_bytes(DATA, "Cats:");
|
63
|
+
set_cursor_position(0, 2);
|
64
|
+
i2c_write_bytes(DATA, "All your base are");
|
65
|
+
set_cursor_position(1, 3);
|
66
|
+
i2c_write_bytes(DATA, "belong to us.");
|
67
|
+
}
|
68
|
+
|
69
|
+
int main() {
|
70
|
+
configure_display("/dev/i2c-1", 0x3c);
|
71
|
+
init_display();
|
72
|
+
test_display();
|
73
|
+
return 0;
|
74
|
+
}
|
@@ -0,0 +1,101 @@
|
|
1
|
+
//
|
2
|
+
// Created by sokkalf on 3/6/16.
|
3
|
+
//
|
4
|
+
|
5
|
+
#include "oled-control.h"
|
6
|
+
#include <ruby.h>
|
7
|
+
|
8
|
+
|
9
|
+
static VALUE set_cursor(VALUE self, VALUE col, VALUE row) {
|
10
|
+
uint8_t c = NUM2UINT(col);
|
11
|
+
uint8_t r = NUM2UINT(row);
|
12
|
+
|
13
|
+
if(!set_cursor_position(c, r))
|
14
|
+
rb_raise(rb_eRuntimeError, "unable to set cursor position");
|
15
|
+
|
16
|
+
return Qtrue;
|
17
|
+
}
|
18
|
+
|
19
|
+
static VALUE write_string(VALUE self, VALUE str) {
|
20
|
+
const char *s = RSTRING_PTR(str);
|
21
|
+
if(!i2c_write_bytes(DATA, s))
|
22
|
+
rb_raise(rb_eRuntimeError, "unable to write string to display");
|
23
|
+
|
24
|
+
return Qtrue;
|
25
|
+
}
|
26
|
+
|
27
|
+
static VALUE init(VALUE self, VALUE i2cbus, VALUE i2caddress) {
|
28
|
+
const char *bus = RSTRING_PTR(i2cbus);
|
29
|
+
uint8_t a = NUM2UINT(i2caddress);
|
30
|
+
|
31
|
+
if(!configure_display(bus, a))
|
32
|
+
rb_raise(rb_eRuntimeError, "can't detect display! Bus/address wrong?");
|
33
|
+
|
34
|
+
if(!init_display())
|
35
|
+
rb_raise(rb_eRuntimeError, "failure initializing display");
|
36
|
+
|
37
|
+
return Qtrue;
|
38
|
+
}
|
39
|
+
|
40
|
+
static VALUE clear(VALUE self) {
|
41
|
+
if(!clear_display())
|
42
|
+
rb_raise(rb_eRuntimeError, "failure clearing display");
|
43
|
+
|
44
|
+
return Qtrue;
|
45
|
+
}
|
46
|
+
|
47
|
+
static VALUE enable(VALUE self) {
|
48
|
+
if(!display_enable()) {
|
49
|
+
rb_raise(rb_eRuntimeError, "error enabling display");
|
50
|
+
}
|
51
|
+
|
52
|
+
return Qtrue;
|
53
|
+
}
|
54
|
+
|
55
|
+
static VALUE disable(VALUE self) {
|
56
|
+
if(!display_disable()) {
|
57
|
+
rb_raise(rb_eRuntimeError, "error disabling display");
|
58
|
+
}
|
59
|
+
|
60
|
+
return Qtrue;
|
61
|
+
}
|
62
|
+
|
63
|
+
static VALUE send_command(VALUE self, VALUE command) {
|
64
|
+
uint8_t cmd = NUM2UINT(command);
|
65
|
+
if(!send_cmd(cmd)) {
|
66
|
+
rb_raise(rb_eRuntimeError, "error sending command");
|
67
|
+
}
|
68
|
+
|
69
|
+
return Qtrue;
|
70
|
+
}
|
71
|
+
|
72
|
+
static VALUE send_raw_command(VALUE self, VALUE command) {
|
73
|
+
uint8_t cmd = NUM2UINT(command);
|
74
|
+
if(!send_raw_cmd(cmd)) {
|
75
|
+
rb_raise(rb_eRuntimeError, "error sending raw command");
|
76
|
+
}
|
77
|
+
|
78
|
+
return Qtrue;
|
79
|
+
}
|
80
|
+
|
81
|
+
static VALUE set_contrast(VALUE self, VALUE level) {
|
82
|
+
uint8_t val = NUM2UINT(level);
|
83
|
+
if(!set_contrast_level(val)) {
|
84
|
+
rb_raise(rb_eRuntimeError, "error setting contrast");
|
85
|
+
}
|
86
|
+
return Qtrue;
|
87
|
+
}
|
88
|
+
|
89
|
+
void Init_oled_control(void) {
|
90
|
+
VALUE klass = rb_define_class("OLED", rb_cObject);
|
91
|
+
|
92
|
+
rb_define_method(klass, "set_cursor", set_cursor, 2);
|
93
|
+
rb_define_method(klass, "clear", clear, 0);
|
94
|
+
rb_define_method(klass, "set_contrast", set_contrast, 1);
|
95
|
+
rb_define_method(klass, "enable", enable, 0);
|
96
|
+
rb_define_method(klass, "disable", disable, 0);
|
97
|
+
rb_define_protected_method(klass, "send_command", send_command, 1);
|
98
|
+
rb_define_protected_method(klass, "send_raw_command", send_raw_command, 1);
|
99
|
+
rb_define_protected_method(klass, "write_string", write_string, 1);
|
100
|
+
rb_define_protected_method(klass, "init", init, 2);
|
101
|
+
}
|
@@ -0,0 +1,136 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include "oled-control.h"
|
4
|
+
|
5
|
+
const char* i2c_bus;
|
6
|
+
int i2c_bus_handle;
|
7
|
+
uint8_t oled_address;
|
8
|
+
int configured = FALSE;
|
9
|
+
|
10
|
+
int i2c_write_byte(uint8_t reg, uint8_t data) {
|
11
|
+
char buf[2];
|
12
|
+
buf[0] = reg;
|
13
|
+
buf[1] = data;
|
14
|
+
if(write(i2c_bus_handle, buf, 2) != 2) {
|
15
|
+
fprintf(stderr, "Write to device failed\n");
|
16
|
+
return FALSE;
|
17
|
+
}
|
18
|
+
return TRUE;
|
19
|
+
}
|
20
|
+
|
21
|
+
int i2c_write_bytes(uint8_t reg, const char* data) {
|
22
|
+
size_t len = sizeof(uint8_t) + strlen(data);
|
23
|
+
// allocate room for reg + data + trailing null character:
|
24
|
+
char *buf = calloc(1, len+1);
|
25
|
+
memcpy(&buf[0], ®, 1);
|
26
|
+
memcpy(&buf[1], data, strlen(data));
|
27
|
+
// write the reg + data, minus the trailing null character
|
28
|
+
if(write(i2c_bus_handle, buf, len) != len) {
|
29
|
+
fprintf(stderr, "Write to device failed\n");
|
30
|
+
free(buf);
|
31
|
+
return FALSE;
|
32
|
+
}
|
33
|
+
free(buf);
|
34
|
+
return TRUE;
|
35
|
+
}
|
36
|
+
|
37
|
+
int set_cursor_position(uint8_t col, uint8_t row) {
|
38
|
+
if((col >= DISPLAY_MAX_COLS) || (row >= DISPLAY_MAX_ROWS))
|
39
|
+
return FALSE;
|
40
|
+
|
41
|
+
int line_offsets[] = {
|
42
|
+
0x00, // start of line 1
|
43
|
+
0x20,
|
44
|
+
0x40,
|
45
|
+
0x60 // start of line 4
|
46
|
+
};
|
47
|
+
return i2c_write_byte(CMD, 0x80 | (col + line_offsets[row]));
|
48
|
+
}
|
49
|
+
|
50
|
+
int clear_display() {
|
51
|
+
return i2c_write_byte(CMD, 0x01);
|
52
|
+
}
|
53
|
+
|
54
|
+
int set_contrast_level(uint8_t level) {
|
55
|
+
return i2c_write_byte(CMD, 0x2A) &&
|
56
|
+
i2c_write_byte(CMD, 0x79) &&
|
57
|
+
i2c_write_byte(CMD, 0x81) &&
|
58
|
+
i2c_write_byte(CMD, level) &&
|
59
|
+
i2c_write_byte(CMD, 0x78) &&
|
60
|
+
i2c_write_byte(CMD, 0x28);
|
61
|
+
}
|
62
|
+
|
63
|
+
int display_enable() {
|
64
|
+
return i2c_write_byte(CMD, 0x0C);
|
65
|
+
}
|
66
|
+
|
67
|
+
int display_disable() {
|
68
|
+
return i2c_write_byte(CMD, 0x08);
|
69
|
+
}
|
70
|
+
|
71
|
+
int send_cmd(uint8_t cmd) {
|
72
|
+
return i2c_write_byte(CMD, 0x2A) &&
|
73
|
+
i2c_write_byte(CMD, cmd) &&
|
74
|
+
i2c_write_byte(CMD, 0x28);
|
75
|
+
}
|
76
|
+
|
77
|
+
int send_raw_cmd(uint8_t cmd) {
|
78
|
+
return i2c_write_byte(CMD, cmd);
|
79
|
+
}
|
80
|
+
|
81
|
+
int configure_display(const char* bus, uint8_t address) {
|
82
|
+
i2c_bus = bus;
|
83
|
+
oled_address = address;
|
84
|
+
if((i2c_bus_handle = open(i2c_bus, O_RDWR)) < 0) {
|
85
|
+
return FALSE;
|
86
|
+
}
|
87
|
+
if (ioctl(i2c_bus_handle, I2C_SLAVE, oled_address) < 0) {
|
88
|
+
return FALSE;
|
89
|
+
}
|
90
|
+
configured = TRUE;
|
91
|
+
return configured;
|
92
|
+
}
|
93
|
+
|
94
|
+
int init_display() {
|
95
|
+
if(!configured)
|
96
|
+
return FALSE;
|
97
|
+
|
98
|
+
return i2c_write_byte(CMD, 0x2a) && // **** Set "RE"=1<--->00101010B
|
99
|
+
i2c_write_byte(CMD, 0x71) &&
|
100
|
+
i2c_write_byte(CMD, 0x5c) &&
|
101
|
+
i2c_write_byte(CMD, 0x28) &&
|
102
|
+
i2c_write_byte(CMD, 0x08) && // display off
|
103
|
+
i2c_write_byte(CMD, 0x2a) &&
|
104
|
+
i2c_write_byte(CMD, 0x79) &&
|
105
|
+
i2c_write_byte(CMD, 0xd5) &&
|
106
|
+
i2c_write_byte(CMD, 0x70) &&
|
107
|
+
i2c_write_byte(CMD, 0x78) &&
|
108
|
+
i2c_write_byte(CMD, 0x09) && // this is a 4 line display. Set to 0x08 for a 2 line display.
|
109
|
+
i2c_write_byte(CMD, 0x06) &&
|
110
|
+
i2c_write_byte(CMD, 0x72) &&
|
111
|
+
i2c_write_byte(DATA, 0x00) &&
|
112
|
+
i2c_write_byte(CMD, 0x2a) &&
|
113
|
+
i2c_write_byte(CMD, 0x79) &&
|
114
|
+
i2c_write_byte(CMD, 0xda) &&
|
115
|
+
i2c_write_byte(CMD, 0x10) &&
|
116
|
+
i2c_write_byte(CMD, 0xdc) &&
|
117
|
+
i2c_write_byte(CMD, 0x00) &&
|
118
|
+
i2c_write_byte(CMD, 0x81) && // set contrast
|
119
|
+
i2c_write_byte(CMD, 0x50) && // contrast level
|
120
|
+
i2c_write_byte(CMD, 0xdb) &&
|
121
|
+
i2c_write_byte(CMD, 0x30) &&
|
122
|
+
i2c_write_byte(CMD, 0xdc) &&
|
123
|
+
i2c_write_byte(CMD, 0x03) &&
|
124
|
+
i2c_write_byte(CMD, 0x78) &&
|
125
|
+
i2c_write_byte(CMD, 0x28) &&
|
126
|
+
i2c_write_byte(CMD, 0x2a) &&
|
127
|
+
i2c_write_byte(CMD, 0x06) && // entry mode (move cursor right, don’t shift display)
|
128
|
+
i2c_write_byte(CMD, 0x28) &&
|
129
|
+
i2c_write_byte(CMD, 0x01) &&
|
130
|
+
i2c_write_byte(CMD, 0x80) &&
|
131
|
+
display_enable() &&
|
132
|
+
!usleep(1000); // spec says to hold on for 0.1 secs before data
|
133
|
+
// usleep returns 0, ergo FALSE, on success, so invert it
|
134
|
+
}
|
135
|
+
|
136
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
//
|
2
|
+
// Created by sokkalf on 3/6/16.
|
3
|
+
//
|
4
|
+
|
5
|
+
#ifndef OLED_CONTROL_OLED_CONTROL_H
|
6
|
+
#define OLED_CONTROL_OLED_CONTROL_H
|
7
|
+
|
8
|
+
#include <stddef.h>
|
9
|
+
#include <linux/i2c-dev.h>
|
10
|
+
#include <fcntl.h>
|
11
|
+
#include <sys/ioctl.h>
|
12
|
+
#include <unistd.h>
|
13
|
+
#include <string.h>
|
14
|
+
#include <stdint.h>
|
15
|
+
|
16
|
+
#define TRUE 1
|
17
|
+
#define FALSE 0
|
18
|
+
|
19
|
+
#define CMD 0x80
|
20
|
+
#define DATA 0x40
|
21
|
+
|
22
|
+
#define DISPLAY_MAX_ROWS 4
|
23
|
+
#define DISPLAY_MAX_COLS 20
|
24
|
+
|
25
|
+
int i2c_write_byte(uint8_t reg, uint8_t data);
|
26
|
+
int i2c_write_bytes(uint8_t reg, const char* data);
|
27
|
+
int set_cursor_position(uint8_t col, uint8_t row);
|
28
|
+
int clear_display();
|
29
|
+
int set_contrast_level(uint8_t level);
|
30
|
+
int display_enable();
|
31
|
+
int display_disable();
|
32
|
+
int send_cmd(uint8_t cmd);
|
33
|
+
int send_raw_cmd(uint8_t cmd);
|
34
|
+
int configure_display(const char* bus, uint8_t address);
|
35
|
+
int init_display();
|
36
|
+
|
37
|
+
#endif //OLED_CONTROL_OLED_CONTROL_H
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'oled-control/oled_control'
|
2
|
+
|
3
|
+
class OLED
|
4
|
+
NORMAL=0x06
|
5
|
+
FLIPPED=0x05
|
6
|
+
|
7
|
+
def initialize(i2c_bus = '/dev/i2c-1', i2c_address = 0x3c, flipped = false)
|
8
|
+
@flipped = flipped
|
9
|
+
|
10
|
+
# the OLED display defines its own weird character set
|
11
|
+
@character_conversion = {
|
12
|
+
0xE5 => 0xAF, # å
|
13
|
+
0xC5 => 0xAE, # Å
|
14
|
+
0xF8 => 0xAC, # ø
|
15
|
+
0xD8 => 0xAB, # Ø
|
16
|
+
0xE6 => 0xBD, # æ
|
17
|
+
0xC6 => 0xBC, # Æ
|
18
|
+
0xD6 => 0x5C, # Ö
|
19
|
+
0xF6 => 0x7C, # ö
|
20
|
+
0xF1 => 0x7D, # ñ
|
21
|
+
0xD1 => 0x5D, # Ñ
|
22
|
+
0xE4 => 0x7B, # ä
|
23
|
+
0xC4 => 0x5B, # Ä
|
24
|
+
0xFC => 0x7E, # ü
|
25
|
+
0xDC => 0x5E, # Ü
|
26
|
+
0xE9 => 0xA5, # é
|
27
|
+
0xC9 => 0xBF, # É
|
28
|
+
0xED => 0xE8, # í
|
29
|
+
0xCD => 0xE3, # Í
|
30
|
+
0xDF => 0xBE, # ß
|
31
|
+
0xE1 => 0xE7, # á
|
32
|
+
0xC1 => 0xE2, # Á
|
33
|
+
0xEA => 0xC7, # ê
|
34
|
+
0xCA => 0xC6, # Ê
|
35
|
+
0x40 => 0xA0, # @
|
36
|
+
0xA4 => 0x24, # ¤
|
37
|
+
0x24 => 0xA2, # $
|
38
|
+
0xA3 => 0xA1, # £
|
39
|
+
0xFA => 0xEA, # ú
|
40
|
+
0xDA => 0xE5, # Ú
|
41
|
+
# unsupported characters are mapped to closest match
|
42
|
+
0xEF => 0x69, # ï -> i
|
43
|
+
0xCF => 0x49, # Ï -> I
|
44
|
+
0xEB => 0x65, # ë -> e
|
45
|
+
0xCB => 0x45, # Ë -> E
|
46
|
+
0xE3 => 0x61, # ã -> a
|
47
|
+
0xC3 => 0x41, # Ã -> A
|
48
|
+
}
|
49
|
+
self.init(i2c_bus, i2c_address)
|
50
|
+
end
|
51
|
+
|
52
|
+
def clear_row(row)
|
53
|
+
set_cursor(0, row)
|
54
|
+
write(" "*20)
|
55
|
+
end
|
56
|
+
|
57
|
+
def command(cmd)
|
58
|
+
self.send_command(cmd)
|
59
|
+
end
|
60
|
+
|
61
|
+
def raw_command(cmd)
|
62
|
+
self.send_raw_command(cmd)
|
63
|
+
end
|
64
|
+
|
65
|
+
def flip
|
66
|
+
@flipped = !@flipped
|
67
|
+
if @flipped
|
68
|
+
command(NORMAL)
|
69
|
+
else
|
70
|
+
command(FLIPPED)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def write(str)
|
75
|
+
unless str.is_a?(String)
|
76
|
+
str = str.to_s
|
77
|
+
end
|
78
|
+
iso_string = str.encode('iso-8859-1')
|
79
|
+
encoded_string = []
|
80
|
+
iso_string.each_byte{|b| encoded_string << (@character_conversion[b.ord].nil? ? b.ord : @character_conversion[b.ord]) }
|
81
|
+
self.write_string(encoded_string.pack("c*"))
|
82
|
+
end
|
83
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oled-control
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Christian Lønaas
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-03-10 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Ruby Gem for SSD1311 based 20x4 OLED display
|
14
|
+
email: christian.lonaas@discombobulator.org
|
15
|
+
executables: []
|
16
|
+
extensions:
|
17
|
+
- ext/oled-control/extconf.rb
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ext/oled-control/extconf.rb
|
21
|
+
- ext/oled-control/main.c
|
22
|
+
- ext/oled-control/oled-control-gem.c
|
23
|
+
- ext/oled-control/oled-control.c
|
24
|
+
- ext/oled-control/oled-control.h
|
25
|
+
- lib/oled-control/oled.rb
|
26
|
+
homepage: https://github.com/sokkalf/oled-control
|
27
|
+
licenses:
|
28
|
+
- MIT
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 2.2.2
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: Control OLED i2c display
|
50
|
+
test_files: []
|