Updates from pi
This commit is contained in:
parent
84612aded5
commit
c1fb89271c
18
RpiLedBars/.vscode/c_cpp_properties.json
vendored
Normal file
18
RpiLedBars/.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "gnu17",
|
||||
"cppStandard": "gnu++14",
|
||||
"intelliSenseMode": "linux-gcc-arm",
|
||||
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
|
||||
"configurationProvider": "ms-vscode.cmake-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
3
RpiLedBars/.vscode/settings.json
vendored
Normal file
3
RpiLedBars/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"cmake.sourceDirectory": "${workspaceFolder}/backend"
|
||||
}
|
@ -7,4 +7,6 @@ set(CMAKE_C_STANDARD 99)
|
||||
|
||||
add_subdirectory(libs)
|
||||
|
||||
configure_file(cava_config ../ COPYONLY)
|
||||
|
||||
add_subdirectory(src)
|
@ -1,5 +1,6 @@
|
||||
# make
|
||||
cp ./bin/pixled bin/service_pixled
|
||||
install -v -D ../build/src/RpiLedBars cava_config -t /opt/pixled/
|
||||
# cp ./bin/pixled bin/service_pixled
|
||||
sudo -s bash -c "cp pixled.service /etc/systemd/system; systemctl daemon-reload"
|
||||
# sudo -s bash -c "systemctl enable pixled"
|
||||
sudo -s bash -c "systemctl restart pixled"
|
@ -1,5 +1,7 @@
|
||||
include(FetchContent)
|
||||
|
||||
set(FETCHCONTENT_FULLY_DISCONNECTED ON)
|
||||
|
||||
FetchContent_Declare(
|
||||
logc
|
||||
GIT_REPOSITORY "https://github.com/Tropicananass/log.c.git"
|
||||
|
@ -1,9 +1,10 @@
|
||||
[Unit]
|
||||
Description=pixled
|
||||
Description=RpiLedBars
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=pixled -n 60 -d 2
|
||||
WorkingDirectory=/opt/pixled
|
||||
ExecStart=/opt/pixled/RpiLedBars -n 60 -d 2
|
||||
Restart=always
|
||||
User=root
|
||||
Group=root
|
||||
|
@ -106,7 +106,7 @@ void set_sensitivity(int channel, int8_t sensitivity8) {
|
||||
} else {
|
||||
param.ledbar[channel].sensitivity = sensitivity;
|
||||
}
|
||||
log_debug("Sensitivity : %f", sensitivity);
|
||||
log_debug("Sensitivity[%d] : %f", channel, sensitivity);
|
||||
}
|
||||
|
||||
void set_hue_base(int channel, int8_t hueBase8) {
|
||||
|
@ -187,7 +187,7 @@ static int start_cava_process() {
|
||||
if (cavaPid == 0) {
|
||||
/* Child process*/
|
||||
// int fdLogOut;
|
||||
char *args[] = {"cava", "-p", "/home/pi/LedBars/RpiLedBars/cava_config", NULL};
|
||||
char *args[] = {"cava", "-p", "./cava_config", NULL};
|
||||
|
||||
/* Close reading end of the pipe */
|
||||
close(fdCavaPipe[0]);
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
int client_fd = -1;
|
||||
|
||||
int channel = LED_NCHANS;
|
||||
|
||||
/***************************************************************************************************
|
||||
* Internal Function Prototypes
|
||||
**************************************************************************************************/
|
||||
@ -77,6 +79,14 @@ void pattern_command_handler(char *payload);
|
||||
|
||||
void color_command_handler(char *payload);
|
||||
|
||||
void modulate_command_handler(char *payload);
|
||||
|
||||
void channel_command_handler(char *payload);
|
||||
|
||||
void sensitivity_command_handler(char *payload);
|
||||
|
||||
void gravity_command_handler(char *payload);
|
||||
|
||||
/***************************************************************************************************
|
||||
* External Function Definitions
|
||||
**************************************************************************************************/
|
||||
@ -142,6 +152,18 @@ void onmessage(int fd, const unsigned char *msg, uint64_t size, int type) {
|
||||
case 'c':
|
||||
color_command_handler(payload);
|
||||
break;
|
||||
case 's':
|
||||
modulate_command_handler(payload);
|
||||
break;
|
||||
case 'h':
|
||||
channel_command_handler(payload);
|
||||
break;
|
||||
case 'e':
|
||||
sensitivity_command_handler(payload);
|
||||
break;
|
||||
case 'g':
|
||||
gravity_command_handler(payload);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_warn("Unkown command in \"%s\"", msgStr);
|
||||
@ -187,8 +209,36 @@ void color_command_handler(char *payload) {
|
||||
log_debug(" - %s", tokenArray[n]);
|
||||
}
|
||||
if (atoi(tokenArray[0]) == 0) {
|
||||
set_hue_base(LED_NCHANS, atoi(tokenArray[1]) * INT8_MAX / HUE_MAX);
|
||||
set_saturation(LED_NCHANS, atoi(tokenArray[2]) * INT8_MAX / 100);
|
||||
set_luminosity(LED_NCHANS, atoi(tokenArray[3]) * INT8_MAX / 100);
|
||||
set_hue_base(channel, atoi(tokenArray[1]) * INT8_MAX / HUE_MAX);
|
||||
set_saturation(channel, atoi(tokenArray[2]) * INT8_MAX / 100);
|
||||
set_luminosity(channel, atoi(tokenArray[3]) * INT8_MAX / 100);
|
||||
} else {
|
||||
set_saturation(channel, atoi(tokenArray[2]) * INT8_MAX / 100);
|
||||
set_luminosity(channel, atoi(tokenArray[3]) * INT8_MAX / 100);
|
||||
}
|
||||
}
|
||||
|
||||
void modulate_command_handler(char *payload) {
|
||||
bool modulate;
|
||||
modulate = strcmp(payload, "true") == 0;
|
||||
log_debug("modulate :%s", modulate ? "true" : "false");
|
||||
set_hue_auto_shift(modulate);
|
||||
}
|
||||
|
||||
void channel_command_handler(char *payload) {
|
||||
int newChannel = atoi(payload);
|
||||
if (0 <= newChannel && newChannel <= LED_NCHANS) {
|
||||
log_debug("Channel: %d", newChannel);
|
||||
channel = newChannel;
|
||||
}
|
||||
}
|
||||
|
||||
void sensitivity_command_handler(char *payload) {
|
||||
int newSensitivity = atoi(payload);
|
||||
set_sensitivity(channel, newSensitivity);
|
||||
}
|
||||
|
||||
void gravity_command_handler(char *payload) {
|
||||
int newGravity = atoi(payload);
|
||||
set_gravity(newGravity);
|
||||
}
|
24
RpiLedBars/cava_config
Normal file
24
RpiLedBars/cava_config
Normal file
@ -0,0 +1,24 @@
|
||||
[general]
|
||||
framerate = 60
|
||||
autosens = 0
|
||||
sensitivity = 200
|
||||
bars = 128
|
||||
|
||||
[input]
|
||||
method = alsa
|
||||
source = plughw:1
|
||||
|
||||
[output]
|
||||
method = raw
|
||||
channels = mono
|
||||
mono_option = left
|
||||
data_format = ascii
|
||||
ascii_max_range=65535
|
||||
bit_format = 16bit
|
||||
|
||||
[smoothing]
|
||||
integral = 77
|
||||
monstercat = 0
|
||||
waves = 0
|
||||
gravity = 0
|
||||
|
@ -38,6 +38,6 @@ server {
|
||||
alias /home/pi/LedBars/RpiLedBars/frontend/web/;
|
||||
# First attempt to serve request as file, then
|
||||
# as directory, then fall back to displaying a 404.
|
||||
try_files $uri $uri/ index.html =404;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,11 @@
|
||||
<div class="modal-body">
|
||||
Try reconnecting in <span id="time-left">60s</span>
|
||||
</div>
|
||||
<form id="ws-input" class="btn-group" role="group" aria-label="Select ws">
|
||||
<input type="radio" class="btn-check" name="ws-selection" id="hotspot-ws" autocomplete="off" value="0" checked>
|
||||
<input type="radio" class="btn-check" name="ws-selection" id="local-ws" autocomplete="off" value="1">
|
||||
<input type="radio" class="btn-check" name="ws-selection" id="distant-ws" autocomplete="off" value="2">
|
||||
</form>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" onclick="{timeout=1;}">Reconnect now</button>
|
||||
</div>
|
||||
@ -72,32 +77,32 @@
|
||||
<div class="col d-flex justify-content-center">
|
||||
<form id="channel-input" class="btn-group" role="group" aria-label="Select channel">
|
||||
<!-- todo: Change to checkbox -->
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="all-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="0-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="1-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="2-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="3-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="4-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="5-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="6-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="7-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="all-channel" autocomplete="off" value="8" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="0-channel" autocomplete="off" value="0">
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="1-channel" autocomplete="off" value="1">
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="2-channel" autocomplete="off" value="2">
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="3-channel" autocomplete="off" value="3">
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="4-channel" autocomplete="off" value="4">
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="5-channel" autocomplete="off" value="5">
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="6-channel" autocomplete="off" value="6">
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="7-channel" autocomplete="off" value="7">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row pt-2 gy-2">
|
||||
<label class="form-label col-9 col-sm-2 text-sm-end" for="formControlRange">Sensitivity</label>
|
||||
<span class="col-3 col-sm-1 text-end">50</span>
|
||||
<span class="col-3 col-sm-1 text-end">64</span>
|
||||
<div class="col col-sm-9">
|
||||
<input type="range" class="form-range" id="formControlRange" oninput="rangeCallback(this)">
|
||||
<input type="range" class="form-range" id="formControlRange" max="127" oninput="sensitivityCallback(this)">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row pt-2 gy-2">
|
||||
<label class="form-label col-9 col-sm-2 text-sm-end" for="formControlRange">Gravity</label>
|
||||
<span class="col-3 col-sm-1 text-end">50</span>
|
||||
<span class="col-3 col-sm-1 text-end">64</span>
|
||||
<div class="col col-sm-9">
|
||||
<input type="range" class="form-range col-auto" id="formControlRange" oninput="rangeCallback(this)">
|
||||
<input type="range" class="form-range col-auto" id="formControlRange" max="127" oninput="gravityCallback(this)">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -22,6 +22,7 @@ function addLabelAndListener(name, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
addLabelAndListener("ws", wsSelectCallback);
|
||||
addLabelAndListener("mode", modeSelectCallback);
|
||||
addLabelAndListener("pattern", patternSelectCallback);
|
||||
addLabelAndListener("channel", channelSelectCallback);
|
||||
@ -74,4 +75,4 @@ var modulationPicker = new iro.ColorPicker('#modulationPicker', {
|
||||
|
||||
reconnect();
|
||||
colorPicker.on("color:change", colorChangeCallback);
|
||||
modulationPicker.on("color:change", colorChangeCallback);
|
||||
modulationPicker.on("color:change", modulationColorChangeCallback);
|
@ -1,3 +1,6 @@
|
||||
var ws_index = 0
|
||||
const ws_address_list = ["ws://192.168.4.1:8080", "ws://192.168.1.130:8080", "ws://tropicananass.ovh:8080"]
|
||||
|
||||
function wait_reconnection() {
|
||||
--timeout;
|
||||
document.getElementById("time-left").innerHTML = timeout + "s";
|
||||
@ -8,7 +11,15 @@ function wait_reconnection() {
|
||||
}
|
||||
|
||||
function reconnect() {
|
||||
socket = new WebSocket("ws://tropicananass.ovh:8080");
|
||||
// for (i in ws_address_list) {
|
||||
// console.log("try to connect " + ws_address_list[i])
|
||||
// try {
|
||||
socket = new WebSocket(ws_address_list[ws_index]);
|
||||
// } catch (error) {
|
||||
// console.error("failed to connect to " + ws_address_list[i] + "\n" + error);
|
||||
// }
|
||||
// }
|
||||
// socket = new WebSocket("ws://192.168.1.130");
|
||||
timeout = 60;
|
||||
|
||||
socket.onopen = function(e) {
|
||||
@ -47,5 +58,10 @@ function reconnect() {
|
||||
|
||||
socket.onerror = function(error) {
|
||||
console.log(`[error] ws: ${error.message}`);
|
||||
++ws_index;
|
||||
if (ws_index >= ws_address_list.length) {
|
||||
ws_index = 0;
|
||||
}
|
||||
document.getElementById("ws-input").elements["ws-selection"][ws_index].checked = true;
|
||||
};
|
||||
}
|
@ -1,3 +1,11 @@
|
||||
function wsSelectCallback(event) {
|
||||
// todo: disable form on this != auto
|
||||
if (event.target.nodeName == 'INPUT') {
|
||||
console.log("ws:" + event.target.value);
|
||||
ws_index = event.target.value;
|
||||
}
|
||||
}
|
||||
|
||||
function modeSelectCallback(event) {
|
||||
// todo: disable form on this != auto
|
||||
if (event.target.nodeName == 'INPUT') {
|
||||
@ -20,28 +28,27 @@ function patternSelectCallback(event) {
|
||||
|
||||
function channelSelectCallback(event) {
|
||||
if (event.target.nodeName == 'INPUT') {
|
||||
channel = event.target.id.split("-")[0];
|
||||
if (channel == "all") {
|
||||
// inputArray = document.getElementById("channel-input").elements[name + "channel-selection"]
|
||||
// for (let inputIndex = 0; inputIndex < inputArray.length; inputIndex++) {
|
||||
// inputArray[inputIndex].checked = false;
|
||||
// }
|
||||
selectedChannel = 8;
|
||||
} else if (channel == "none") {
|
||||
inputArray = document.getElementById("channel-input").elements[name + "channel-selection"]
|
||||
for (let inputIndex = 0; inputIndex < inputArray.length; inputIndex++) {
|
||||
inputArray[inputIndex].checked = false;
|
||||
console.log("h:" + event.target.value);
|
||||
if (socket.readyState == WebSocket.OPEN) {
|
||||
socket.send("h:" + event.target.value);
|
||||
}
|
||||
selectedChannel = -1;
|
||||
} else {
|
||||
inputArray = document.getElementById("channelGlobal-input").elements[name + "channelGlobal-selection"]
|
||||
for (let inputIndex = 0; inputIndex < inputArray.length; inputIndex++) {
|
||||
inputArray[inputIndex].checked = false;
|
||||
}
|
||||
selectedChannel = channel;
|
||||
}
|
||||
|
||||
function sensitivityCallback(element) {
|
||||
console.log("e:" + element.value);
|
||||
if (socket.readyState == WebSocket.OPEN) {
|
||||
socket.send("e:" + element.value);
|
||||
}
|
||||
console.log("channel:" + selectedChannel);
|
||||
rangeCallback(element);
|
||||
}
|
||||
|
||||
function gravityCallback(element) {
|
||||
console.log("g:" + element.value);
|
||||
if (socket.readyState == WebSocket.OPEN) {
|
||||
socket.send("g:" + element.value);
|
||||
}
|
||||
rangeCallback(element);
|
||||
}
|
||||
|
||||
var eventd;
|
||||
@ -54,6 +61,9 @@ function colorModulateCallback(element) {
|
||||
document.getElementById("modulationPicker").classList.add("d-none");
|
||||
}
|
||||
console.log("s: " + element.checked);
|
||||
if (socket.readyState == WebSocket.OPEN) {
|
||||
socket.send("s:" + element.checked);
|
||||
}
|
||||
}
|
||||
|
||||
function colorChangeCallback(color) {
|
||||
@ -63,6 +73,13 @@ function colorChangeCallback(color) {
|
||||
}
|
||||
}
|
||||
|
||||
function modulationColorChangeCallback(color) {
|
||||
console.log("c: " + (color.index + 2) + ", h: " + color.hsl.h + ", s: " + color.hsl.s + ", l: " + color.hsl.l + "}");
|
||||
if (socket.readyState == WebSocket.OPEN) {
|
||||
socket.send("c:" + (color.index + 2) + "," + color.hsl.h + "," + color.hsl.s + "," + color.hsl.l);
|
||||
}
|
||||
}
|
||||
|
||||
function rangeCallback(element) {
|
||||
eventd = this
|
||||
element.parentNode.parentElement.getElementsByTagName('span')[0].innerText = element.value;
|
||||
|
@ -1,33 +1,93 @@
|
||||
<template>
|
||||
<div class="bg-dark text-white">
|
||||
<div class="bg-dark text-white">
|
||||
<div class="container">
|
||||
<div class="row py-4 text-center" id="header">
|
||||
<h1> Tropicananass Leds </h1>
|
||||
<h1>Tropicananass Leds</h1>
|
||||
</div>
|
||||
|
||||
<Reconnect></Reconnect>
|
||||
|
||||
<ModeSelect :mode_list="{Test, Artnet, Auto, Manual}"></ModeSelect>
|
||||
<ModeSelect mode_list="{Test, Artnet, Auto, Manual}"></ModeSelect>
|
||||
|
||||
<div class="row pt-2 gy-2">
|
||||
<div class="col d-flex justify-content-center">
|
||||
<form id="mode-input" class="btn-group" role="group" aria-label="Select mode">
|
||||
<input type="radio" class="btn-check" name="mode-selection" id="test-mode" autocomplete="off" value="0" checked>
|
||||
<input type="radio" class="btn-check" name="mode-selection" id="artnet-mode" autocomplete="off" value="1">
|
||||
<input type="radio" class="btn-check" name="mode-selection" id="auto-mode" autocomplete="off" value="2">
|
||||
<input type="radio" class="btn-check" name="mode-selection" id="manual-mode" autocomplete="off" value="3">
|
||||
<form
|
||||
id="mode-input"
|
||||
class="btn-group"
|
||||
role="group"
|
||||
aria-label="Select mode"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="mode-selection"
|
||||
id="test-mode"
|
||||
autocomplete="off"
|
||||
value="0"
|
||||
checked
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="mode-selection"
|
||||
id="artnet-mode"
|
||||
autocomplete="off"
|
||||
value="1"
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="mode-selection"
|
||||
id="auto-mode"
|
||||
autocomplete="off"
|
||||
value="2"
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="mode-selection"
|
||||
id="manual-mode"
|
||||
autocomplete="off"
|
||||
value="3"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col d-flex justify-content-center">
|
||||
<form id="pattern-input" class="btn-group" role="group" aria-label="Select pattern">
|
||||
<input type="radio" class="btn-check" name="pattern-selection" id="pulse-pattern" autocomplete="off" value="0" checked>
|
||||
<input type="radio" class="btn-check" name="pattern-selection" id="travel-pattern" autocomplete="off" value="1">
|
||||
<input type="radio" class="btn-check" name="pattern-selection" id="strobe-pattern" autocomplete="off" value="2">
|
||||
<form
|
||||
id="pattern-input"
|
||||
class="btn-group"
|
||||
role="group"
|
||||
aria-label="Select pattern"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="pattern-selection"
|
||||
id="pulse-pattern"
|
||||
autocomplete="off"
|
||||
value="0"
|
||||
checked
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="pattern-selection"
|
||||
id="travel-pattern"
|
||||
autocomplete="off"
|
||||
value="1"
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="pattern-selection"
|
||||
id="strobe-pattern"
|
||||
autocomplete="off"
|
||||
value="2"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row pt-2 gy-2">
|
||||
<legend class="col-12 col-sm-auto">Channel</legend>
|
||||
<!-- <div class="col d-flex justify-content-center">
|
||||
@ -37,87 +97,199 @@
|
||||
</form>
|
||||
</div> -->
|
||||
<div class="col d-flex justify-content-center">
|
||||
<form id="channel-input" class="btn-group" role="group" aria-label="Select channel">
|
||||
<form
|
||||
id="channel-input"
|
||||
class="btn-group"
|
||||
role="group"
|
||||
aria-label="Select channel"
|
||||
>
|
||||
<!-- todo: Change to checkbox -->
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="all-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="0-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="1-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="2-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="3-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="4-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="5-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="6-channel" autocomplete="off" checked>
|
||||
<input type="radio" class="btn-check" name="channel-selection" id="7-channel" autocomplete="off" checked>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="channel-selection"
|
||||
id="all-channel"
|
||||
autocomplete="off"
|
||||
checked
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="channel-selection"
|
||||
id="0-channel"
|
||||
autocomplete="off"
|
||||
checked
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="channel-selection"
|
||||
id="1-channel"
|
||||
autocomplete="off"
|
||||
checked
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="channel-selection"
|
||||
id="2-channel"
|
||||
autocomplete="off"
|
||||
checked
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="channel-selection"
|
||||
id="3-channel"
|
||||
autocomplete="off"
|
||||
checked
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="channel-selection"
|
||||
id="4-channel"
|
||||
autocomplete="off"
|
||||
checked
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="channel-selection"
|
||||
id="5-channel"
|
||||
autocomplete="off"
|
||||
checked
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="channel-selection"
|
||||
id="6-channel"
|
||||
autocomplete="off"
|
||||
checked
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="channel-selection"
|
||||
id="7-channel"
|
||||
autocomplete="off"
|
||||
checked
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row pt-2 gy-2">
|
||||
<label class="form-label col-9 col-sm-2 text-sm-end" for="formControlRange">Sensitivity</label>
|
||||
<label
|
||||
class="form-label col-9 col-sm-2 text-sm-end"
|
||||
for="formControlRange"
|
||||
>Sensitivity</label
|
||||
>
|
||||
<span class="col-3 col-sm-1 text-end">50</span>
|
||||
<div class="col col-sm-9">
|
||||
<input type="range" class="form-range" id="formControlRange" oninput="rangeCallback(this)">
|
||||
<input
|
||||
type="range"
|
||||
class="form-range"
|
||||
id="formControlRange"
|
||||
oninput="rangeCallback(this)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row pt-2 gy-2">
|
||||
<label class="form-label col-9 col-sm-2 text-sm-end" for="formControlRange">Gravity</label>
|
||||
<label
|
||||
class="form-label col-9 col-sm-2 text-sm-end"
|
||||
for="formControlRange"
|
||||
>Gravity</label
|
||||
>
|
||||
<span class="col-3 col-sm-1 text-end">50</span>
|
||||
<div class="col col-sm-9">
|
||||
<input type="range" class="form-range col-auto" id="formControlRange" oninput="rangeCallback(this)">
|
||||
<input
|
||||
type="range"
|
||||
class="form-range col-auto"
|
||||
id="formControlRange"
|
||||
oninput="rangeCallback(this)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row pt-2 gy-2">
|
||||
<div class="col">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="modulateColor" onclick="colorModulateCallback(this)">
|
||||
<label class="form-check-label" for="modulateColor">Modulate color</label>
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
id="modulateColor"
|
||||
onclick="colorModulateCallback(this)"
|
||||
/>
|
||||
<label class="form-check-label" for="modulateColor"
|
||||
>Modulate color</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row pt-2 gy-2">
|
||||
<div id="mainPicker" class="col d-flex justify-content-center"></div>
|
||||
<div id="modulationPicker" class="col d-none d-flex justify-content-center"></div>
|
||||
<div
|
||||
id="modulationPicker"
|
||||
class="col d-none d-flex justify-content-center"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div class="row pt-2 gy-2">
|
||||
<label class="form-label col-9 col-sm-2 text-sm-end" for="formControlRange">Modulation speed</label>
|
||||
<label
|
||||
class="form-label col-9 col-sm-2 text-sm-end"
|
||||
for="formControlRange"
|
||||
>Modulation speed</label
|
||||
>
|
||||
<span class="col-3 col-sm-auto text-end" id="rangeval">50</span>
|
||||
<div class="col col-sm-9">
|
||||
<input type="range" class="form-range col-auto" id="formControlRange" oninput="rangeCallback(this)">
|
||||
<input
|
||||
type="range"
|
||||
class="form-range col-auto"
|
||||
id="formControlRange"
|
||||
oninput="rangeCallback(this)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row pt-2 gy-2">
|
||||
<label class="form-label col-9 col-sm-2 text-sm-end" for="formControlRange">Freq</label>
|
||||
<label
|
||||
class="form-label col-9 col-sm-2 text-sm-end"
|
||||
for="formControlRange"
|
||||
>Freq</label
|
||||
>
|
||||
<span class="col-3 col-sm-auto text-end" id="rangeval">50</span>
|
||||
<div class="col col-sm-9">
|
||||
<input type="range" class="form-range col-auto" id="formControlRange" oninput="rangeCallback(this)">
|
||||
<input
|
||||
type="range"
|
||||
class="form-range col-auto"
|
||||
id="formControlRange"
|
||||
oninput="rangeCallback(this)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Hello !!</h1>
|
||||
<img alt="Vue logo" src="./assets/logo.png">
|
||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
||||
<img alt="Vue logo" src="./assets/logo.png" />
|
||||
<HelloWorld msg="Welcome to Your Vue.js App" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Reconnect from './components/Reconnect.vue'
|
||||
import ModeSelect from './components/ModeSelect.vue'
|
||||
import Reconnect from "./components/Reconnect.vue";
|
||||
import ModeSelect from "./components/ModeSelect.vue";
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
name: "App",
|
||||
components: {
|
||||
Reconnect,
|
||||
ModeSelect
|
||||
}
|
||||
}
|
||||
ModeSelect,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
<style></style>
|
||||
|
18
RpiLedBars/install.sh
Normal file
18
RpiLedBars/install.sh
Normal file
@ -0,0 +1,18 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
target=pi_hotspot
|
||||
dir_target=~/RpiLedBars
|
||||
|
||||
# I - Copy project to pi target
|
||||
## 1 - select target from ssh config
|
||||
|
||||
## 2 - rsync project
|
||||
rsync -avz --delete --backup-dir=../RpiLedBars_backup/"$(date +%F_%H-%M-%S)" ./ -e ssh ${target}:${dir_target}
|
||||
|
||||
# II - Connect to pi target
|
||||
## 1 - Check prequistite (cava, i2s micropphone module, CMake)
|
||||
|
||||
## 2 - Build project
|
||||
ssh ${target} "cd ${dir_target}/frontend && "
|
||||
|
||||
## 3 - Install project
|
@ -1,5 +1,10 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
###
|
||||
# This is a test script for testing rgb led strip reacting to i2S microphone input.
|
||||
# This do not use hardware acceleration.
|
||||
###
|
||||
|
||||
import alsaaudio
|
||||
import audioop
|
||||
import board
|
||||
|
Loading…
Reference in New Issue
Block a user