Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added brightness control to hub75 and i75 #962

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions drivers/hub75/hub75.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ void Hub75::update(PicoGraphics *graphics) {
uint8_t r = (col & 0xff0000) >> 16;
uint8_t g = (col & 0x00ff00) >> 8;
uint8_t b = (col & 0x0000ff) >> 0;
apply_brightness(&r, &g, &b);
set_pixel(x, y, r, g, b);
p++;
}
Expand All @@ -269,10 +270,105 @@ void Hub75::update(PicoGraphics *graphics) {
uint8_t r = (col & 0b1111100000000000) >> 8;
uint8_t g = (col & 0b0000011111100000) >> 3;
uint8_t b = (col & 0b0000000000011111) << 3;
apply_brightness(&r, &g, &b);
set_pixel(x, y, r, g, b);
p++;
}
}
}
}

void Hub75::set_brightness(uint8_t brightness)
{
/* Clamp brightness to a sensible value, 0 - 100 */
if(brightness > 100) {
user_brightness = 100;
}
else {
user_brightness = brightness;
}
}

uint8_t Hub75::get_brightness()
{
return user_brightness;
}

void Hub75::apply_brightness(uint8_t *r, uint8_t *g, uint8_t *b) {
uint8_t h, s, v;
uint8_t rgbMin, rgbMax;

/* If brightness is set full, no point in doing work. */
if(user_brightness > 98 ) {
return;
}

/* And if it's turned right down, it's off. */
if(user_brightness < 2 ) {
*r = *g = *b = 0;
return;
}

/* Convert RGB to HSV. */
rgbMin = *r < *g ? (*r < *b ? *r : *b) : (*g < *b ? *g : *b);
rgbMax = *r > *g ? (*r > *b ? *r : *b) : (*g > *b ? *g : *b);
v = rgbMax;
if(v == 0) {
h = s = 0;
} else {
s = 255 * long(rgbMax - rgbMin) / v;
if(s == 0) {
h = 0;
} else {
if(rgbMax == *r) {
h = 0 + 43 * (*g - *b) / (rgbMax - rgbMin);
} else if(rgbMax == *g) {
h = 85 + 43 * (*b - *r) / (rgbMax - rgbMin);
} else {
h = 171 + 43 * (*r - *g) / (rgbMax - rgbMin);
}
}
}

/* Apply the brightness factor to V. */
v = v * user_brightness / 100;

/* And then convert it *back* to RGB. */
uint8_t region,remainder, p, q, t;
if(s == 0)
{
*r = *g = *b = v;
return;
}
region = h / 43;
remainder = (h - (region * 43)) * 6;
p = (v * (255 - s)) >> 8;
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
switch(region)
{
case 0:
*r = v; *g = t; *b = p;
break;
case 1:
*r = q; *g = v; *b = p;
break;
case 2:
*r = p; *g = v; *b = t;
break;
case 3:
*r = p; *g = q; *b = v;
break;
case 4:
*r = t; *g = p; *b = v;
break;
default:
*r = v; *g = p; *b = q;
break;
}

/* All done! */
return;
}

}
7 changes: 7 additions & 0 deletions drivers/hub75/hub75.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class Hub75 {

uint brightness = 6;

uint8_t user_brightness = 100;


// Top half of display - 16 rows on a 32x32 panel
unsigned int pin_r0 = 0;
Expand Down Expand Up @@ -138,5 +140,10 @@ class Hub75 {
void stop(irq_handler_t handler);
void dma_complete();
void update(PicoGraphics *graphics);
void set_brightness(uint8_t brightness);
uint8_t get_brightness();

private:
void apply_brightness(uint8_t *r, uint8_t *g, uint8_t *b);
};
}
32 changes: 32 additions & 0 deletions micropython/examples/interstate75/brightness.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from interstate75 import Interstate75
import jpegdec
import time

# Create the Interstate display
i75 = Interstate75(display=Interstate75.DISPLAY_INTERSTATE75_32X32)
graphics = i75.display

# Clear the screen
graphics.set_pen(graphics.create_pen(0, 0, 0))
graphics.clear()

# Load and render a jpeg
img = jpegdec.JPEG(graphics)
img.open_file("sun.jpg")
img.decode(0, 0, jpegdec.JPEG_SCALE_FULL, dither=False)

# Set up a brightness variance
delta = -1
brightness = 100

# And loop as we do it
while True:
start = time.ticks_ms()

i75.set_brightness(brightness)
brightness = brightness + delta
if brightness > 100 or brightness < 1:
delta = delta * -1
i75.update(graphics)

print("total took: {} ms".format(time.ticks_ms() - start))
Binary file added micropython/examples/interstate75/sun.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 13 additions & 1 deletion micropython/modules/hub75/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,16 @@ Calling `.clear()` will clear the whole contents of the display

```python
matrix.clear()
```
```

### Setting the brightness

You can set the global brightness of the whole display; the brightness is an
integer value between `0` (off) and `100` (fully on):

```python
matrix.set_brightness(75)
```

If unset, the brightness of the display defaults to 100. You can also query the
current brightness setting with `.get_brightness()`.
4 changes: 4 additions & 0 deletions micropython/modules/hub75/hub75.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(Hub75_clear_obj, Hub75_clear);
MP_DEFINE_CONST_FUN_OBJ_1(Hub75_start_obj, Hub75_start);
MP_DEFINE_CONST_FUN_OBJ_1(Hub75_stop_obj, Hub75_stop);
MP_DEFINE_CONST_FUN_OBJ_2(Hub75_update_obj, Hub75_update);
MP_DEFINE_CONST_FUN_OBJ_2(Hub75_set_brightness_obj, Hub75_set_brightness);
MP_DEFINE_CONST_FUN_OBJ_1(Hub75_get_brightness_obj, Hub75_get_brightness);


/***** Binding of Methods *****/
Expand All @@ -18,6 +20,8 @@ static const mp_rom_map_elem_t Hub75_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&Hub75_start_obj) },
{ MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&Hub75_stop_obj) },
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&Hub75_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_brightness), MP_ROM_PTR(&Hub75_set_brightness_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_brightness), MP_ROM_PTR(&Hub75_get_brightness_obj) },
};

static MP_DEFINE_CONST_DICT(Hub75_locals_dict, Hub75_locals_dict_table);
Expand Down
13 changes: 13 additions & 0 deletions micropython/modules/hub75/hub75.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,19 @@ mp_obj_t Hub75_update(mp_obj_t self_in, mp_obj_t graphics_in) {
return mp_const_none;
}

mp_obj_t Hub75_set_brightness(mp_obj_t self_in, mp_obj_t brightness) {
_Hub75_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Hub75_obj_t);

self->hub75->set_brightness(mp_obj_get_int(brightness));

return mp_const_none;
}

mp_obj_t Hub75_get_brightness(mp_obj_t self_in) {
_Hub75_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Hub75_obj_t);
return mp_obj_new_int(self->hub75->get_brightness());
}

mp_obj_t Hub75_start(mp_obj_t self_in) {
_Hub75_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Hub75_obj_t);
self->hub75->start(dma_complete);
Expand Down
4 changes: 3 additions & 1 deletion micropython/modules/hub75/hub75.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ extern mp_obj_t Hub75_start(mp_obj_t self_in);
extern mp_obj_t Hub75_stop(mp_obj_t self_in);
extern mp_obj_t Hub75_set_pixel(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t Hub75_clear(mp_obj_t self_in);
extern mp_obj_t Hub75_update(mp_obj_t self_in, mp_obj_t graphics_in);
extern mp_obj_t Hub75_update(mp_obj_t self_in, mp_obj_t graphics_in);
extern mp_obj_t Hub75_set_brightness(mp_obj_t self_in, mp_obj_t brightness);
extern mp_obj_t Hub75_get_brightness(mp_obj_t self_in);
21 changes: 21 additions & 0 deletions micropython/modules_py/interstate75.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,27 @@ board.set_led(0, 255, 0) # Makes the LED Blue
board.set_led(0, 0, 255) # Makes the LED Green
```

### Brightness

The Interstate has a global brightness, that affects the entire display. By
default, the display is set to full, but this can be changed via the following
method.

`.set_brightness(n)`

Where n is a value between 0 (off) and 100 (full brightness)

The current brightness of the display can be also be queried:

`.get_brightness()`


example:

```python
board.set_brightness(50) # Sets the display to half-brightness
```

## Display

The display is all handled by our custom picographics drivers they can be accessed via `.display`.
Expand Down
6 changes: 6 additions & 0 deletions micropython/modules_py/interstate75.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,9 @@ def switch_pressed(self, switch):

def set_led(self, r, g, b):
self.__rgb.set_rgb(r, g, b)

def set_brightness(self, brightness):
self.hub75.set_brightness(brightness)

def get_brightness(self):
return self.hub75.get_brightness()