a lot of new stuff
This commit is contained in:
		@@ -21,4 +21,39 @@ biblio:
 | 
				
			|||||||
  * ws2812 with dma/smi from Jeremy P Bentham :
 | 
					  * ws2812 with dma/smi from Jeremy P Bentham :
 | 
				
			||||||
    * ws2812 - https://iosoft.blog/2020/09/29/raspberry-pi-multi-channel-ws2812/
 | 
					    * ws2812 - https://iosoft.blog/2020/09/29/raspberry-pi-multi-channel-ws2812/
 | 
				
			||||||
    * dma - https://iosoft.blog/2020/05/25/raspberry-pi-dma-programming/
 | 
					    * dma - https://iosoft.blog/2020/05/25/raspberry-pi-dma-programming/
 | 
				
			||||||
    * smi - https://iosoft.blog/2020/07/16/raspberry-pi-smi/
 | 
					    * smi - https://iosoft.blog/2020/07/16/raspberry-pi-smi/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Raspi Config :
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					https://makersportal.com/blog/recording-stereo-audio-on-a-raspberry-pi
 | 
				
			||||||
 | 
					https://learn.adafruit.com/adafruit-i2s-mems-microphone-breakout/raspberry-pi-wiring-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sudo apt install python3-pip
 | 
				
			||||||
 | 
					sudo pip3 install --upgrade adafruit-python-shell
 | 
				
			||||||
 | 
					cd /tmp
 | 
				
			||||||
 | 
					sudo wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/i2smic.py
 | 
				
			||||||
 | 
					sudo python3 i2smic.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# plug microphone
 | 
				
			||||||
 | 
					sudo reboot
 | 
				
			||||||
 | 
					arecord -l
 | 
				
			||||||
 | 
					arecord -D plughw:1 -c1 -r 48000 -f S32_LE -t wav -V mono -v file.wav
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Control record volume
 | 
				
			||||||
 | 
					cp res/.asoundrc ~/.asoundrc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# alsa API
 | 
				
			||||||
 | 
					http://www.equalarea.com/paul/alsa-audio.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# for project
 | 
				
			||||||
 | 
					sudo apt install libasound2-dev wiringpi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# for cava
 | 
				
			||||||
 | 
					sudo apt install libfftw3-dev libasound2-dev libtool automake
 | 
				
			||||||
 | 
					./autogen.sh
 | 
				
			||||||
 | 
					./configure
 | 
				
			||||||
 | 
					make
 | 
				
			||||||
 | 
					sudo make install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Access point
 | 
				
			||||||
 | 
					grep "Access point conf" $(find /etc -type f)
 | 
				
			||||||
@@ -3,7 +3,7 @@ Description=pixled
 | 
				
			|||||||
After=network.target
 | 
					After=network.target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Service]
 | 
					[Service]
 | 
				
			||||||
ExecStart=pixled -n 180 -d 2
 | 
					ExecStart=pixled -n 60 -d 2
 | 
				
			||||||
Restart=always
 | 
					Restart=always
 | 
				
			||||||
User=root
 | 
					User=root
 | 
				
			||||||
Group=root
 | 
					Group=root
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "rpi_midi_controller.h"
 | 
					#include "rpi_midi_controller.h"
 | 
				
			||||||
#include "rpi_param.h"
 | 
					#include "rpi_param.h"
 | 
				
			||||||
 | 
					#include "rpi_pattern.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***************************************************************************************************
 | 
					/***************************************************************************************************
 | 
				
			||||||
 * Preprocessor Constants and Macros
 | 
					 * Preprocessor Constants and Macros
 | 
				
			||||||
@@ -40,7 +41,6 @@
 | 
				
			|||||||
 **************************************************************************************************/
 | 
					 **************************************************************************************************/
 | 
				
			||||||
/*  Command-line parameters */
 | 
					/*  Command-line parameters */
 | 
				
			||||||
bool IsTestMode = false;
 | 
					bool IsTestMode = false;
 | 
				
			||||||
int chanLedCount = 0;
 | 
					 | 
				
			||||||
int logLevel = 2;
 | 
					int logLevel = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int previousMode = -1;
 | 
					int previousMode = -1;
 | 
				
			||||||
@@ -79,9 +79,6 @@ void log_lock_helper(bool lock, void *udata);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int main(int argc, char const *argv[]) {
 | 
					int main(int argc, char const *argv[]) {
 | 
				
			||||||
  // setup
 | 
					  // setup
 | 
				
			||||||
  parseCommandLineArgs(argc, argv);
 | 
					 | 
				
			||||||
  log_set_level(logLevel);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  signal(SIGINT, terminate);
 | 
					  signal(SIGINT, terminate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  struct sched_param sp;
 | 
					  struct sched_param sp;
 | 
				
			||||||
@@ -98,7 +95,7 @@ int main(int argc, char const *argv[]) {
 | 
				
			|||||||
  selector_setup();
 | 
					  selector_setup();
 | 
				
			||||||
  leddriver_setup();
 | 
					  leddriver_setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // setup_cava();
 | 
					  parseCommandLineArgs(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // loop
 | 
					  // loop
 | 
				
			||||||
  while (1) {
 | 
					  while (1) {
 | 
				
			||||||
@@ -149,7 +146,7 @@ void parseCommandLineArgs(int argc, char const *argv[]) {
 | 
				
			|||||||
          log_error("no numeric value");
 | 
					          log_error("no numeric value");
 | 
				
			||||||
          exit(-EXIT_FAILURE);
 | 
					          exit(-EXIT_FAILURE);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          chanLedCount = atoi(argv[++args]);
 | 
					          param_access->pixled.chanLedCount = atoi(argv[++args]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case 'D': // -D: debug level
 | 
					      case 'D': // -D: debug level
 | 
				
			||||||
@@ -158,6 +155,7 @@ void parseCommandLineArgs(int argc, char const *argv[]) {
 | 
				
			|||||||
          exit(-EXIT_FAILURE);
 | 
					          exit(-EXIT_FAILURE);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          logLevel = atoi(argv[++args]);
 | 
					          logLevel = atoi(argv[++args]);
 | 
				
			||||||
 | 
					          log_set_level(logLevel);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case 'T': // -T: test mode
 | 
					      case 'T': // -T: test mode
 | 
				
			||||||
@@ -189,6 +187,7 @@ void manage_tasks(int previousMode, int currentMode) {
 | 
				
			|||||||
    artnet_stop();
 | 
					    artnet_stop();
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  case 2:
 | 
					  case 2:
 | 
				
			||||||
 | 
					  case 3:
 | 
				
			||||||
    cava_stop();
 | 
					    cava_stop();
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  default:
 | 
					  default:
 | 
				
			||||||
@@ -201,6 +200,7 @@ void manage_tasks(int previousMode, int currentMode) {
 | 
				
			|||||||
    artnet_start();
 | 
					    artnet_start();
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  case 2:
 | 
					  case 2:
 | 
				
			||||||
 | 
					  case 3:
 | 
				
			||||||
    cava_start();
 | 
					    cava_start();
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  default:
 | 
					  default:
 | 
				
			||||||
@@ -241,13 +241,14 @@ void execute_test_mode() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  static int i = 0, offset = 0;
 | 
					  static int i = 0, offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (size_t ledIndex = 0; ledIndex < chanLedCount; ++ledIndex) {
 | 
					  for (size_t ledIndex = 0; ledIndex < param_access->pixled.chanLedCount; ++ledIndex) {
 | 
				
			||||||
    set_color(ledIndex <= offset % chanLedCount ? on_rgbs[i] * .5 : off_rgbs, ledIndex);
 | 
					    set_color(ledIndex <= offset % param_access->pixled.chanLedCount ? on_rgbs[i] * .5 : off_rgbs,
 | 
				
			||||||
 | 
					              ledIndex);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  leddriver_refresh();
 | 
					  leddriver_refresh();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (offset < chanLedCount) {
 | 
					  if (offset < param_access->pixled.chanLedCount) {
 | 
				
			||||||
    ++offset;
 | 
					    ++offset;
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    offset = 0;
 | 
					    offset = 0;
 | 
				
			||||||
@@ -267,7 +268,7 @@ void execute_artnet_mode() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for (size_t ledBar = 0; ledBar < LED_NCHANS; ledBar++) {
 | 
					  for (size_t ledBar = 0; ledBar < LED_NCHANS; ledBar++) {
 | 
				
			||||||
    if (artnet_get_dmx_data(ledBar, &dmxData) == 0) {
 | 
					    if (artnet_get_dmx_data(ledBar, &dmxData) == 0) {
 | 
				
			||||||
      for (size_t i = 0; i < chanLedCount; ++i) {
 | 
					      for (size_t i = 0; i < param_access->pixled.chanLedCount; ++i) {
 | 
				
			||||||
        uint8_t *rgb = dmxData + (i * 3);
 | 
					        uint8_t *rgb = dmxData + (i * 3);
 | 
				
			||||||
        rgb_data[i][ledBar] = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
 | 
					        rgb_data[i][ledBar] = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
 | 
				
			||||||
        rgb_txdata(rgb_data[i], i);
 | 
					        rgb_txdata(rgb_data[i], i);
 | 
				
			||||||
@@ -278,17 +279,39 @@ void execute_artnet_mode() {
 | 
				
			|||||||
  leddriver_refresh();
 | 
					  leddriver_refresh();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t static const minHue = 120 * UINT16_MAX / 360;
 | 
					 | 
				
			||||||
uint16_t static const maxHue = 300 * UINT16_MAX / 360;
 | 
					 | 
				
			||||||
uint16_t static const hueInterval = UINT16_MAX - (maxHue - minHue);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void execute_autonomous_mode() {
 | 
					void execute_autonomous_mode() {
 | 
				
			||||||
  int ret;
 | 
					  int ret;
 | 
				
			||||||
  uint16_t *buffer;
 | 
					  uint16_t *buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ((ret = cava_get_buffer(&buffer)) == 0) {
 | 
				
			||||||
 | 
					    switch (param_access->auton.pattern) {
 | 
				
			||||||
 | 
					    case 0:
 | 
				
			||||||
 | 
					      bounce_led_and_color(buffer, CAVA_BAR_NUMBER);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 1:
 | 
				
			||||||
 | 
					      bounce_led(buffer, CAVA_BAR_NUMBER);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 2:
 | 
				
			||||||
 | 
					      bounce_led_and_travel(buffer, CAVA_BAR_NUMBER);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned baseLed[LED_NCHANS] = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void execute_manual_mode() {
 | 
				
			||||||
 | 
					  int ret;
 | 
				
			||||||
 | 
					  uint16_t *buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((ret = cava_get_buffer(&buffer)) == 0) {
 | 
					  if ((ret = cava_get_buffer(&buffer)) == 0) {
 | 
				
			||||||
    for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
 | 
					    for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
 | 
				
			||||||
      uint16_t barMax = 0;
 | 
					      uint16_t barMax = 0;
 | 
				
			||||||
 | 
					      // uint16_t hueInterval = UINT16_MAX - (param_access->ledbar[ledBarIndex].hueInterval -
 | 
				
			||||||
 | 
					      //                                      param_access->ledbar[ledBarIndex].hueBase);
 | 
				
			||||||
      for (size_t cavaBar = 0; cavaBar < CAVA_BAR_NUMBER / LED_NCHANS; ++cavaBar) {
 | 
					      for (size_t cavaBar = 0; cavaBar < CAVA_BAR_NUMBER / LED_NCHANS; ++cavaBar) {
 | 
				
			||||||
        unsigned barIndex = ledBarIndex * CAVA_BAR_NUMBER / LED_NCHANS + cavaBar;
 | 
					        unsigned barIndex = ledBarIndex * CAVA_BAR_NUMBER / LED_NCHANS + cavaBar;
 | 
				
			||||||
        if (barMax < buffer[barIndex]) {
 | 
					        if (barMax < buffer[barIndex]) {
 | 
				
			||||||
@@ -296,16 +319,17 @@ void execute_autonomous_mode() {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      barMax *= param_access->auton.sensitivity * param_access->ledbar[ledBarIndex].sensitivity;
 | 
					      barMax *= param_access->auton.sensitivity * param_access->ledbar[ledBarIndex].sensitivity;
 | 
				
			||||||
      unsigned ledToLight = barMax * chanLedCount / UINT16_MAX;
 | 
					      unsigned ledToLight = barMax * param_access->pixled.chanLedCount / 2 / UINT16_MAX;
 | 
				
			||||||
      unsigned long hueShift = (long)barMax * (long)hueInterval / hueInterval;
 | 
					      unsigned long hueShift =
 | 
				
			||||||
      uint16_t hue = minHue - hueShift;
 | 
					          (long)barMax * (long)param_access->ledbar[ledBarIndex].hueInterval / UINT16_MAX;
 | 
				
			||||||
      uint32_t color = ColorHSV(hue, 255, 100);
 | 
					      uint16_t hue = param_access->ledbar[ledBarIndex].hueBase - hueShift;
 | 
				
			||||||
 | 
					      uint32_t color = ColorHSV(hue, 255, param_access->ledbar[ledBarIndex].luminosity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for (size_t i = 0; i < ledToLight; ++i) {
 | 
					      for (size_t i = 0; i < ledToLight; ++i) {
 | 
				
			||||||
        rgb_data[i][ledBarIndex] = color;
 | 
					        rgb_data[i][ledBarIndex] = color;
 | 
				
			||||||
        rgb_txdata(rgb_data[i], i);
 | 
					        rgb_txdata(rgb_data[i], i);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      for (size_t i = ledToLight; i < chanLedCount; ++i) {
 | 
					      for (size_t i = ledToLight; i < param_access->pixled.chanLedCount; ++i) {
 | 
				
			||||||
        rgb_data[i][ledBarIndex] = 0x000000;
 | 
					        rgb_data[i][ledBarIndex] = 0x000000;
 | 
				
			||||||
        rgb_txdata(rgb_data[i], i);
 | 
					        rgb_txdata(rgb_data[i], i);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -315,16 +339,6 @@ void execute_autonomous_mode() {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void execute_manual_mode() {
 | 
					 | 
				
			||||||
  for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
 | 
					 | 
				
			||||||
    for (size_t i = 0; i < chanLedCount; ++i) {
 | 
					 | 
				
			||||||
      rgb_data[i][ledBarIndex] = 0x000000;
 | 
					 | 
				
			||||||
      rgb_txdata(rgb_data[i], i);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  leddriver_refresh();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void adjust_loop(struct timespec const *loopStart) {
 | 
					void adjust_loop(struct timespec const *loopStart) {
 | 
				
			||||||
  struct timespec loopEnd;
 | 
					  struct timespec loopEnd;
 | 
				
			||||||
  long elapsedTimeUs, remainingTimeUs;
 | 
					  long elapsedTimeUs, remainingTimeUs;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,8 @@
 | 
				
			|||||||
 * Preprocessor Constants and Macros
 | 
					 * Preprocessor Constants and Macros
 | 
				
			||||||
 **************************************************************************************************/
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define C3 0x30
 | 
					#define C3 48
 | 
				
			||||||
 | 
					#define Gd3 56
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***************************************************************************************************
 | 
					/***************************************************************************************************
 | 
				
			||||||
 * Type and Contant Definitions
 | 
					 * Type and Contant Definitions
 | 
				
			||||||
@@ -161,35 +162,52 @@ void handle_in_port_events(snd_seq_event_t *ev) {
 | 
				
			|||||||
        destChannel = ev->data.control.value;
 | 
					        destChannel = ev->data.control.value;
 | 
				
			||||||
        log_info("Control param channel %d", ev->data.control.value);
 | 
					        log_info("Control param channel %d", ev->data.control.value);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else if (destChannel != GLOBAL_CHANNEL) {
 | 
				
			||||||
      log_debug("PGMCHANGE : ch %#04x - param %u - value %d", ev->data.control.channel,
 | 
					      log_info("Control global param");
 | 
				
			||||||
                ev->data.control.param, ev->data.control.value);
 | 
					      destChannel = GLOBAL_CHANNEL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case SND_SEQ_EVENT_NOTEON:
 | 
					  case SND_SEQ_EVENT_NOTEON:
 | 
				
			||||||
    if (ev->data.note.note == C3) {
 | 
					    if (ev->data.note.note == C3) {
 | 
				
			||||||
      if (destChannel != 0xf) {
 | 
					      if (destChannel != GLOBAL_CHANNEL) {
 | 
				
			||||||
        destChannel = 0xf;
 | 
					        destChannel = GLOBAL_CHANNEL;
 | 
				
			||||||
        log_info("Control global param");
 | 
					        log_info("Control global param");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					    } else if (ev->data.note.note >= Gd3) {
 | 
				
			||||||
 | 
					      set_pattern(ev->data.note.note - Gd3);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      log_debug("NOTEON : ch %#04x - note %d - vel %d", ev->data.note.channel, ev->data.note.note,
 | 
					      log_debug("NOTEON : ch %#04x - note %d - vel %d", ev->data.note.channel, ev->data.note.note,
 | 
				
			||||||
                ev->data.note.velocity);
 | 
					                ev->data.note.velocity);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  case SND_SEQ_EVENT_NOTEOFF:
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case SND_SEQ_EVENT_CONTROLLER:
 | 
					  case SND_SEQ_EVENT_CONTROLLER:
 | 
				
			||||||
    switch (ev->data.control.param) {
 | 
					    switch (ev->data.control.param) {
 | 
				
			||||||
    case 1:
 | 
					    case 1:
 | 
				
			||||||
      set_sensitivity(destChannel, ev->data.control.value + 1);
 | 
					      set_sensitivity(destChannel, ev->data.control.value);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 2:
 | 
				
			||||||
 | 
					      set_luminosity(destChannel, ev->data.control.value);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 3:
 | 
				
			||||||
 | 
					      set_hue_base(destChannel, ev->data.control.value);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 4:
 | 
				
			||||||
 | 
					      set_hue_interval(destChannel, ev->data.control.value);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 5:
 | 
				
			||||||
 | 
					      set_gravity(ev->data.control.value);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
 | 
					      log_debug("CONTROLLER : ch %#04x - param %u - value %d", ev->data.control.channel,
 | 
				
			||||||
 | 
					                ev->data.control.param, ev->data.control.value);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    log_debug("CONTROLLER : ch %#04x - param %u - value %d", ev->data.control.channel,
 | 
					 | 
				
			||||||
              ev->data.control.param, ev->data.control.value);
 | 
					 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  default:
 | 
					  default:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,8 +8,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "rpi_param.h"
 | 
					#include "rpi_param.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***************************************************************************************************
 | 
					/***************************************************************************************************
 | 
				
			||||||
 * Preprocessor Constants and Macros
 | 
					 * Preprocessor Constants and Macros
 | 
				
			||||||
 **************************************************************************************************/
 | 
					 **************************************************************************************************/
 | 
				
			||||||
@@ -18,9 +21,10 @@
 | 
				
			|||||||
 * Type and Contant Definitions
 | 
					 * Type and Contant Definitions
 | 
				
			||||||
 **************************************************************************************************/
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pixled_param_t const dummyPixledParam = {.intensity = .5, .hue = 0};
 | 
					pixled_param_t const dummyPixledParam = {.chanLedCount = 0};
 | 
				
			||||||
auton_param_t const dummyAutonParam = {.sensitivity = 1};
 | 
					auton_param_t const dummyAutonParam = {.sensitivity = 10, .gravity = 80, .pattern = 2};
 | 
				
			||||||
ledbar_param_t const dummyLedbarParam = {.sensitivity = 1};
 | 
					ledbar_param_t const dummyLedbarParam = {
 | 
				
			||||||
 | 
					    .sensitivity = 1., .hueBase = 121, .hueInterval = -100, .luminosity = 20, .saturation = 255};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***************************************************************************************************
 | 
					/***************************************************************************************************
 | 
				
			||||||
 * Persistent Variables
 | 
					 * Persistent Variables
 | 
				
			||||||
@@ -39,18 +43,74 @@ param_t param;
 | 
				
			|||||||
void param_setup() {
 | 
					void param_setup() {
 | 
				
			||||||
  param.pixled = dummyPixledParam;
 | 
					  param.pixled = dummyPixledParam;
 | 
				
			||||||
  param.auton = dummyAutonParam;
 | 
					  param.auton = dummyAutonParam;
 | 
				
			||||||
  for (size_t i = 0; i < 10; ++i) {
 | 
					  for (size_t i = 0; i < LED_NCHANS; ++i) {
 | 
				
			||||||
    param.ledbar[i] = dummyLedbarParam;
 | 
					    param.ledbar[i] = dummyLedbarParam;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  param_access = ¶m;
 | 
					  param_access = ¶m;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void set_sensitivity(int channel, unsigned int sensitivity) {
 | 
					void set_pattern(unsigned int pattern) {
 | 
				
			||||||
  if (channel >= 10) {
 | 
					  if (pattern != param.auton.pattern) {
 | 
				
			||||||
 | 
					    param.auton.pattern = pattern;
 | 
				
			||||||
 | 
					    log_debug("Pattern : %d", pattern);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void set_gravity(int8_t gravity8) {
 | 
				
			||||||
 | 
					  param.auton.gravity = gravity8 * 100 / INT8_MAX;
 | 
				
			||||||
 | 
					  log_debug("Gravity : %d", param.auton.gravity);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void set_sensitivity(int channel, int8_t sensitivity8) {
 | 
				
			||||||
 | 
					  float sensitivity = pow(1.065, sensitivity8 - INT8_MAX / 2);
 | 
				
			||||||
 | 
					  if (channel >= LED_NCHANS) {
 | 
				
			||||||
    param.auton.sensitivity = sensitivity;
 | 
					    param.auton.sensitivity = sensitivity;
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    param.ledbar[channel].sensitivity = sensitivity;
 | 
					    param.ledbar[channel].sensitivity = sensitivity;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  log_debug("Sensitivity : %f", sensitivity);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void set_hue_base(int channel, int8_t hueBase8) {
 | 
				
			||||||
 | 
					  uint16_t hueBase = hueBase8 * HUEBASE_MAX / INT8_MAX;
 | 
				
			||||||
 | 
					  if (channel < LED_NCHANS) {
 | 
				
			||||||
 | 
					    param.ledbar[channel].hueBase = hueBase;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    for (size_t i = 0; i < LED_NCHANS; ++i) {
 | 
				
			||||||
 | 
					      param.ledbar[i].hueBase = hueBase;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  log_debug("Hue base : %u", hueBase);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void set_hue_interval(int channel, int8_t hueInterval8) {
 | 
				
			||||||
 | 
					  int16_t hueInterval = hueInterval8 - ((INT8_MAX + 1) / 2);
 | 
				
			||||||
 | 
					  if (hueInterval != 0) {
 | 
				
			||||||
 | 
					    hueInterval = hueInterval * HUEINTERVAL_MAX / (INT8_MAX / 2);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (channel < LED_NCHANS) {
 | 
				
			||||||
 | 
					    param.ledbar[channel].hueInterval = hueInterval;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    for (size_t i = 0; i < LED_NCHANS; ++i) {
 | 
				
			||||||
 | 
					      param.ledbar[i].hueInterval = hueInterval;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  log_debug("Hue interval [%2d] : %d - [%u, %hu]", channel, hueInterval,
 | 
				
			||||||
 | 
					            param.ledbar[0].hueBase * UINT16_MAX / HUE_MAX,
 | 
				
			||||||
 | 
					            (param.ledbar[0].hueBase + hueInterval) * UINT16_MAX / HUE_MAX);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void set_luminosity(int channel, int8_t luminosity8) {
 | 
				
			||||||
 | 
					  uint8_t luminosity = luminosity8 * UINT8_MAX / INT8_MAX;
 | 
				
			||||||
 | 
					  if (channel < LED_NCHANS) {
 | 
				
			||||||
 | 
					    param.ledbar[channel].luminosity = luminosity;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    for (size_t i = 0; i < LED_NCHANS; ++i) {
 | 
				
			||||||
 | 
					      param.ledbar[i].luminosity = luminosity;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  log_debug("Luminosity : %u", luminosity);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***************************************************************************************************
 | 
					/***************************************************************************************************
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,18 @@
 | 
				
			|||||||
#define CHAN_MAXLEDS 6 * 60 // Maximum number of LEDs per channel
 | 
					#define CHAN_MAXLEDS 6 * 60 // Maximum number of LEDs per channel
 | 
				
			||||||
#define LED_NCHANS 8        // Number of LED channels (8 or 16)
 | 
					#define LED_NCHANS 8        // Number of LED channels (8 or 16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GLOBAL_CHANNEL 15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HUE_MAX 359
 | 
				
			||||||
 | 
					#define HUEBASE_MIN 0
 | 
				
			||||||
 | 
					#define HUEBASE_MAX HUE_MAX
 | 
				
			||||||
 | 
					#define HUEINTERVAL_MIN -HUE_MAX
 | 
				
			||||||
 | 
					#define HUEINTERVAL_MAX HUE_MAX
 | 
				
			||||||
 | 
					#define LUMINOSITY_MIN 0
 | 
				
			||||||
 | 
					#define LUMINOSITY_MAX 255
 | 
				
			||||||
 | 
					#define SATURATION_MIN 0
 | 
				
			||||||
 | 
					#define SATURATION_MAX 255
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***************************************************************************************************
 | 
					/***************************************************************************************************
 | 
				
			||||||
 * Type and Contant Definitions
 | 
					 * Type and Contant Definitions
 | 
				
			||||||
 **************************************************************************************************/
 | 
					 **************************************************************************************************/
 | 
				
			||||||
@@ -26,22 +38,27 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  uint8_t intensity;
 | 
					  unsigned int chanLedCount;
 | 
				
			||||||
  int hue;
 | 
					 | 
				
			||||||
} pixled_param_t;
 | 
					} pixled_param_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  unsigned int sensitivity;
 | 
					  float sensitivity;
 | 
				
			||||||
 | 
					  unsigned int gravity;
 | 
				
			||||||
 | 
					  unsigned int pattern;
 | 
				
			||||||
} auton_param_t;
 | 
					} auton_param_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  unsigned int sensitivity;
 | 
					  float sensitivity;
 | 
				
			||||||
 | 
					  unsigned int hueBase;
 | 
				
			||||||
 | 
					  int hueInterval;
 | 
				
			||||||
 | 
					  unsigned int luminosity;
 | 
				
			||||||
 | 
					  unsigned int saturation;
 | 
				
			||||||
} ledbar_param_t;
 | 
					} ledbar_param_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -50,7 +67,7 @@ typedef struct {
 | 
				
			|||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  pixled_param_t pixled;
 | 
					  pixled_param_t pixled;
 | 
				
			||||||
  auton_param_t auton;
 | 
					  auton_param_t auton;
 | 
				
			||||||
  ledbar_param_t ledbar[10];
 | 
					  ledbar_param_t ledbar[LED_NCHANS];
 | 
				
			||||||
} param_t;
 | 
					} param_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***************************************************************************************************
 | 
					/***************************************************************************************************
 | 
				
			||||||
@@ -68,13 +85,33 @@ param_t *param_access;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void param_setup();
 | 
					void param_setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param[in] pattern
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void set_pattern(unsigned int pattern);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param[in] pattern
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void set_gravity(int8_t gravity8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * \brief
 | 
					 * \brief
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \param[in] channel
 | 
					 * \param[in] channel
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \param[in] sensitivity
 | 
					 * \param[in] sensitivity8
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void set_sensitivity(int channel, unsigned int sensitivity);
 | 
					void set_sensitivity(int channel, int8_t sensitivity8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void set_hue_base(int channel, int8_t hueBase8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void set_hue_interval(int channel, int8_t hueInterval8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void set_luminosity(int channel, int8_t luminosity8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __RPI_PARAM_H__ */
 | 
					#endif /* __RPI_PARAM_H__ */
 | 
				
			||||||
							
								
								
									
										207
									
								
								RpiLedBars/src/rpi_pattern.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								RpiLedBars/src/rpi_pattern.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,207 @@
 | 
				
			|||||||
 | 
					/** \file .c
 | 
				
			||||||
 | 
					 *  \brief This module
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * Includes
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rpi_pattern.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "drivers/leddriver/rpi_leddriver.h"
 | 
				
			||||||
 | 
					#include "rpi_param.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * Preprocessor Constants and Macros
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * Type and Contant Definitions
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * Persistent Variables
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * RGB data buffer. Persistency is not needed but, as of it size, it must be declared in heap
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int rgbData[CHAN_MAXLEDS][LED_NCHANS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Number of led previously lighted per led bar
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int lightedLedCountArray[LED_NCHANS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Index of first previously lighted per led bar
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int baseLedIndexArray[LED_NCHANS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * Internal Function Prototypes
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t get_max_on_interval(uint16_t *array, unsigned int length, size_t intervalMin,
 | 
				
			||||||
 | 
					                             size_t intervalSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t apply_sensitivity(uint16_t value, unsigned int valueIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int get_led_to_light_count(uint16_t barValue, unsigned int barIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int get_first_led_to_light(unsigned int barIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * External Function Definitions
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bounce_led_and_color(uint16_t *spectrumArray, unsigned int spectrumLength) {
 | 
				
			||||||
 | 
					  for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
 | 
				
			||||||
 | 
					    size_t intervalSize = spectrumLength / LED_NCHANS;
 | 
				
			||||||
 | 
					    uint16_t barMax = 0;
 | 
				
			||||||
 | 
					    unsigned int ledToLightCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    barMax = get_max_on_interval(spectrumArray, spectrumLength, ledBarIndex * intervalSize,
 | 
				
			||||||
 | 
					                                 intervalSize);
 | 
				
			||||||
 | 
					    barMax = apply_sensitivity(barMax, ledBarIndex);
 | 
				
			||||||
 | 
					    ledToLightCount = get_led_to_light_count(barMax, ledBarIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int hueShift = (long)(ledToLightCount - 1) * param_access->ledbar[ledBarIndex].hueInterval /
 | 
				
			||||||
 | 
					                   (long)param_access->pixled.chanLedCount;
 | 
				
			||||||
 | 
					    uint16_t hue = param_access->ledbar[ledBarIndex].hueBase + hueShift;
 | 
				
			||||||
 | 
					    // log_trace("light %u leds on bar %u - hueShift : %d, hue %u", ledToLightCount, ledBarIndex,
 | 
				
			||||||
 | 
					    //           hueShift, hue);
 | 
				
			||||||
 | 
					    uint32_t color =
 | 
				
			||||||
 | 
					        ColorHSV(hue * UINT16_MAX / HUEBASE_MAX, param_access->ledbar[ledBarIndex].saturation,
 | 
				
			||||||
 | 
					                 param_access->ledbar[ledBarIndex].luminosity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (size_t i = 0; i < ledToLightCount; ++i) {
 | 
				
			||||||
 | 
					      rgbData[i][ledBarIndex] = color;
 | 
				
			||||||
 | 
					      rgb_txdata(rgbData[i], i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for (size_t i = ledToLightCount; i < param_access->pixled.chanLedCount; ++i) {
 | 
				
			||||||
 | 
					      rgbData[i][ledBarIndex] = 0x000000;
 | 
				
			||||||
 | 
					      rgb_txdata(rgbData[i], i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  leddriver_refresh();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bounce_led(uint16_t *spectrumArray, unsigned int spectrumLength) {
 | 
				
			||||||
 | 
					  for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
 | 
				
			||||||
 | 
					    size_t intervalSize = spectrumLength / LED_NCHANS;
 | 
				
			||||||
 | 
					    uint16_t barMax = 0;
 | 
				
			||||||
 | 
					    unsigned int ledToLightCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    barMax = get_max_on_interval(spectrumArray, spectrumLength, ledBarIndex * intervalSize,
 | 
				
			||||||
 | 
					                                 intervalSize);
 | 
				
			||||||
 | 
					    barMax = apply_sensitivity(barMax, ledBarIndex);
 | 
				
			||||||
 | 
					    ledToLightCount = get_led_to_light_count(barMax, ledBarIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (size_t i = 0; i < ledToLightCount; ++i) {
 | 
				
			||||||
 | 
					      unsigned long hueShift = (long)i * param_access->ledbar[ledBarIndex].hueInterval /
 | 
				
			||||||
 | 
					                               (long)param_access->pixled.chanLedCount;
 | 
				
			||||||
 | 
					      uint16_t hue = param_access->ledbar[ledBarIndex].hueBase + hueShift;
 | 
				
			||||||
 | 
					      uint32_t color =
 | 
				
			||||||
 | 
					          ColorHSV(hue * UINT16_MAX / HUEBASE_MAX, param_access->ledbar[ledBarIndex].saturation,
 | 
				
			||||||
 | 
					                   param_access->ledbar[ledBarIndex].luminosity);
 | 
				
			||||||
 | 
					      rgbData[i][ledBarIndex] = color;
 | 
				
			||||||
 | 
					      rgb_txdata(rgbData[i], i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for (size_t i = ledToLightCount; i < param_access->pixled.chanLedCount; ++i) {
 | 
				
			||||||
 | 
					      rgbData[i][ledBarIndex] = 0x000000;
 | 
				
			||||||
 | 
					      rgb_txdata(rgbData[i], i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  leddriver_refresh();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bounce_led_and_travel(uint16_t *spectrumArray, unsigned int spectrumLength) {
 | 
				
			||||||
 | 
					  for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
 | 
				
			||||||
 | 
					    size_t intervalSize = spectrumLength / LED_NCHANS;
 | 
				
			||||||
 | 
					    uint16_t barMax = 0;
 | 
				
			||||||
 | 
					    unsigned int ledToLightCount = 0, firstLedToLight = get_first_led_to_light(ledBarIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    barMax = get_max_on_interval(spectrumArray, spectrumLength, ledBarIndex * intervalSize,
 | 
				
			||||||
 | 
					                                 intervalSize);
 | 
				
			||||||
 | 
					    barMax = apply_sensitivity(barMax, ledBarIndex) / 4;
 | 
				
			||||||
 | 
					    ledToLightCount = get_led_to_light_count(barMax, ledBarIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned long hueShift = (long)(ledToLightCount - 1) * 4L *
 | 
				
			||||||
 | 
					                             param_access->ledbar[ledBarIndex].hueInterval /
 | 
				
			||||||
 | 
					                             (long)param_access->pixled.chanLedCount;
 | 
				
			||||||
 | 
					    uint16_t hue = param_access->ledbar[ledBarIndex].hueBase + hueShift;
 | 
				
			||||||
 | 
					    uint32_t color =
 | 
				
			||||||
 | 
					        ColorHSV(hue * UINT16_MAX / HUEBASE_MAX, param_access->ledbar[ledBarIndex].saturation,
 | 
				
			||||||
 | 
					                 param_access->ledbar[ledBarIndex].luminosity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (size_t i = 0; i < ledToLightCount; ++i) {
 | 
				
			||||||
 | 
					      unsigned int ledIndex = firstLedToLight + i;
 | 
				
			||||||
 | 
					      ledIndex = ledIndex < param_access->pixled.chanLedCount
 | 
				
			||||||
 | 
					                     ? ledIndex
 | 
				
			||||||
 | 
					                     : ledIndex - param_access->pixled.chanLedCount;
 | 
				
			||||||
 | 
					      rgbData[ledIndex][ledBarIndex] = color;
 | 
				
			||||||
 | 
					      rgb_txdata(rgbData[ledIndex], ledIndex);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for (size_t i = ledToLightCount; i < param_access->pixled.chanLedCount; ++i) {
 | 
				
			||||||
 | 
					      unsigned int ledIndex = firstLedToLight + i;
 | 
				
			||||||
 | 
					      ledIndex = ledIndex < param_access->pixled.chanLedCount
 | 
				
			||||||
 | 
					                     ? ledIndex
 | 
				
			||||||
 | 
					                     : ledIndex - param_access->pixled.chanLedCount;
 | 
				
			||||||
 | 
					      rgbData[ledIndex][ledBarIndex] = 0x000000;
 | 
				
			||||||
 | 
					      rgb_txdata(rgbData[ledIndex], ledIndex);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  leddriver_refresh();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * Internal Function Definitions
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t get_max_on_interval(uint16_t *array, unsigned int length, size_t intervalMin,
 | 
				
			||||||
 | 
					                             size_t intervalSize) {
 | 
				
			||||||
 | 
					  uint16_t barMax = 0;
 | 
				
			||||||
 | 
					  for (size_t i = 0; i < intervalSize; ++i) {
 | 
				
			||||||
 | 
					    unsigned barIndex = intervalMin + i;
 | 
				
			||||||
 | 
					    if (barMax < array[barIndex]) {
 | 
				
			||||||
 | 
					      barMax = array[barIndex];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return barMax;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t apply_sensitivity(uint16_t value, unsigned int valueIndex) {
 | 
				
			||||||
 | 
					  return value * param_access->auton.sensitivity * param_access->ledbar[valueIndex].sensitivity;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int get_led_to_light_count(uint16_t barValue, unsigned int barIndex) {
 | 
				
			||||||
 | 
					  unsigned int nbLightedLed = lightedLedCountArray[barIndex];
 | 
				
			||||||
 | 
					  unsigned int ledToLightCount = barValue * param_access->pixled.chanLedCount / UINT16_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (ledToLightCount < nbLightedLed) {
 | 
				
			||||||
 | 
					    /* apply gravity */
 | 
				
			||||||
 | 
					    ledToLightCount = ((ledToLightCount * (100 - param_access->auton.gravity)) +
 | 
				
			||||||
 | 
					                       (nbLightedLed * param_access->auton.gravity)) /
 | 
				
			||||||
 | 
					                      100;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  lightedLedCountArray[barIndex] = ledToLightCount;
 | 
				
			||||||
 | 
					  return ledToLightCount;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int get_first_led_to_light(unsigned int barIndex) {
 | 
				
			||||||
 | 
					  unsigned int firstLed = baseLedIndexArray[barIndex];
 | 
				
			||||||
 | 
					  if (lightedLedCountArray[barIndex] != 0) {
 | 
				
			||||||
 | 
					    firstLed += lightedLedCountArray[barIndex] / 4 + 1;
 | 
				
			||||||
 | 
					    firstLed = firstLed < param_access->pixled.chanLedCount
 | 
				
			||||||
 | 
					                   ? firstLed
 | 
				
			||||||
 | 
					                   : firstLed - param_access->pixled.chanLedCount;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  baseLedIndexArray[barIndex] = firstLed;
 | 
				
			||||||
 | 
					  return firstLed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								RpiLedBars/src/rpi_pattern.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								RpiLedBars/src/rpi_pattern.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					/** \file .h
 | 
				
			||||||
 | 
					 *  \brief This module
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(__RPI_PATTERN_H__)
 | 
				
			||||||
 | 
					#define __RPI_PATTERN_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * Includes
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * Preprocessor Constants and Macros
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * Type and Contant Definitions
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * Global Variables
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************************************
 | 
				
			||||||
 | 
					 * External Function Prototypes
 | 
				
			||||||
 | 
					 **************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param[in] spectrumArray array of value from spectral analysis
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param[in] spectrumLength length of spectrum array
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void bounce_led_and_color(uint16_t *spectrumArray, unsigned int spectrumLength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param[in] spectrumArray array of value from spectral analysis
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param[in] spectrumLength length of spectrum array
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void bounce_led(uint16_t *spectrumArray, unsigned int spectrumLength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param[in] spectrumArray array of value from spectral analysis
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param[in] spectrumLength length of spectrum array
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void bounce_led_and_travel(uint16_t *spectrumArray, unsigned int spectrumLength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __RPI_PATTERN_H__ */
 | 
				
			||||||
		Reference in New Issue
	
	Block a user