From b1352ac6c43c80cf0625e0bd81874106d4eccf2f Mon Sep 17 00:00:00 2001
From: William Fish <wfish001@gold.ac.uk>
Date: Thu, 22 Feb 2018 11:44:14 +0000
Subject: [PATCH] led progress

---
 LEDprogress/src/WS2812.cpp       | 114 ++++++++++++++++++++++
 LEDprogress/src/WS2812.h         |  99 ++++++++++++++++++++
 LEDprogress/src/cRGB.h           | 115 +++++++++++++++++++++++
 LEDprogress/src/light_ws2812.cpp | 156 +++++++++++++++++++++++++++++++
 LEDprogress/src/main.cpp         |  13 +++
 LEDprogress/src/ofApp.cpp        | 114 ++++++++++++++++++++++
 LEDprogress/src/ofApp.h          |  34 +++++++
 7 files changed, 645 insertions(+)
 create mode 100644 LEDprogress/src/WS2812.cpp
 create mode 100644 LEDprogress/src/WS2812.h
 create mode 100644 LEDprogress/src/cRGB.h
 create mode 100644 LEDprogress/src/light_ws2812.cpp
 create mode 100644 LEDprogress/src/main.cpp
 create mode 100644 LEDprogress/src/ofApp.cpp
 create mode 100644 LEDprogress/src/ofApp.h

diff --git a/LEDprogress/src/WS2812.cpp b/LEDprogress/src/WS2812.cpp
new file mode 100644
index 0000000..10d5596
--- /dev/null
+++ b/LEDprogress/src/WS2812.cpp
@@ -0,0 +1,114 @@
+/*
+* light weight WS2812 lib V2.1 - Arduino support
+*
+* Controls WS2811/WS2812/WS2812B RGB-LEDs
+* Author: Matthias Riegler
+*
+* Mar 07 2014: Added Arduino and C++ Library
+*
+* September 6, 2014:	Added option to switch between most popular color orders
+*						(RGB, GRB, and BRG) --  Windell H. Oskay
+* 
+* License: GNU GPL v2 (see License.txt)
+*/
+
+#include "WS2812.h"
+#include <stdlib.h>
+
+WS2812::WS2812(uint16_t num_leds) {
+	count_led = num_leds;
+	
+	pixels = (uint8_t*)malloc(count_led*3);
+	#ifdef RGB_ORDER_ON_RUNTIME	
+		offsetGreen = 0;
+		offsetRed = 1;
+		offsetBlue = 2;
+	#endif
+}
+
+cRGB WS2812::get_crgb_at(uint16_t index) {
+	
+	cRGB px_value;
+	
+	if(index < count_led) {
+		
+		uint16_t tmp;
+		tmp = index * 3;
+
+		px_value.r = pixels[OFFSET_R(tmp)];
+		px_value.g = pixels[OFFSET_G(tmp)];
+		px_value.b = pixels[OFFSET_B(tmp)];
+	}
+	
+	return px_value;
+}
+
+uint8_t WS2812::set_crgb_at(uint16_t index, cRGB px_value) {
+	
+	if(index < count_led) {
+		
+		uint16_t tmp;
+		tmp = index * 3;
+		
+		pixels[OFFSET_R(tmp)] = px_value.r;
+		pixels[OFFSET_G(tmp)] = px_value.g;
+		pixels[OFFSET_B(tmp)] = px_value.b;		
+		return 0;
+	} 
+	return 1;
+}
+
+uint8_t WS2812::set_subpixel_at(uint16_t index, uint8_t offset, uint8_t px_value) {
+	if (index < count_led) {
+		uint16_t tmp;
+		tmp = index * 3;
+
+		pixels[tmp + offset] = px_value;
+		return 0;
+	}
+	return 1;
+}
+
+void WS2812::sync() {
+	*ws2812_port_reg |= pinMask; // Enable DDR
+	ws2812_sendarray_mask(pixels,3*count_led,pinMask,(uint8_t*) ws2812_port,(uint8_t*) ws2812_port_reg );	
+}
+
+#ifdef RGB_ORDER_ON_RUNTIME	
+void WS2812::setColorOrderGRB() { // Default color order
+	offsetGreen = 0;
+	offsetRed = 1;
+	offsetBlue = 2;
+}
+
+void WS2812::setColorOrderRGB() {
+	offsetRed = 0;
+	offsetGreen = 1;
+	offsetBlue = 2;
+}
+
+void WS2812::setColorOrderBRG() {
+	offsetBlue = 0;
+	offsetRed = 1;
+	offsetGreen = 2;
+}
+#endif
+
+WS2812::~WS2812() {
+	free(pixels);
+	
+}
+
+#ifndef ARDUINO
+void WS2812::setOutput(const volatile uint8_t* port, volatile uint8_t* reg, uint8_t pin) {
+	pinMask = (1<<pin);
+	ws2812_port = port;
+	ws2812_port_reg = reg;
+}
+#else
+void WS2812::setOutput(uint8_t pin) {
+	pinMask = digitalPinToBitMask(pin);
+	ws2812_port = portOutputRegister(digitalPinToPort(pin));
+	ws2812_port_reg = portModeRegister(digitalPinToPort(pin));
+}
+#endif 
\ No newline at end of file
diff --git a/LEDprogress/src/WS2812.h b/LEDprogress/src/WS2812.h
new file mode 100644
index 0000000..e571650
--- /dev/null
+++ b/LEDprogress/src/WS2812.h
@@ -0,0 +1,99 @@
+/*
+* light weight WS2812 lib V2.1 - Arduino support
+*
+* Controls WS2811/WS2812/WS2812B RGB-LEDs
+* Author: Matthias Riegler
+*
+* Mar 07 2014: Added Arduino and C++ Library
+*
+* September 6, 2014      Added option to switch between most popular color orders
+*                          (RGB, GRB, and BRG) --  Windell H. Oskay
+* 
+* January 24, 2015       Added option to make color orders static again
+*                        Moved cRGB to a header so it is easier to replace / expand 
+*                              (added SetHSV based on code from kasperkamperman.com)
+*                                              -- Freezy
+*
+* License: GNU GPL v2 (see License.txt)
+*/
+
+#ifndef WS2812_H_
+#define WS2812_H_
+
+#include <avr/interrupt.h>
+#include <avr/io.h>
+#ifndef F_CPU
+#define  F_CPU 16000000UL
+#endif
+#include <util/delay.h>
+#include <stdint.h>
+
+#ifdef ARDUINO
+#if (ARDUINO >= 100)
+#include <Arduino.h>
+#else
+#include <WProgram.h>
+#include <pins_arduino.h>
+#endif
+#endif
+
+//Easier to change cRGB into any other rgb struct
+#include "cRGB.h"
+
+// If you want to use the setColorOrder functions, enable this line
+#define RGB_ORDER_ON_RUNTIME
+
+#ifdef RGB_ORDER_ON_RUNTIME	
+	#define OFFSET_R(r) r+offsetRed
+	#define OFFSET_G(g) g+offsetGreen
+	#define OFFSET_B(b) b+offsetBlue
+#else
+// CHANGE YOUR STATIC RGB ORDER HERE
+	#define OFFSET_R(r) r+1
+	#define OFFSET_G(g) g	
+	#define OFFSET_B(b) b+2	
+#endif
+
+class WS2812 {
+public: 
+	WS2812(uint16_t num_led);
+	~WS2812();
+	
+	#ifndef ARDUINO
+	void setOutput(const volatile uint8_t* port, volatile uint8_t* reg, uint8_t pin);
+	#else
+	void setOutput(uint8_t pin);
+	#endif
+	
+	cRGB get_crgb_at(uint16_t index);
+	uint8_t set_crgb_at(uint16_t index, cRGB px_value);
+	uint8_t set_subpixel_at(uint16_t index, uint8_t offset, uint8_t px_value);
+
+	void sync();
+	
+#ifdef RGB_ORDER_ON_RUNTIME	
+	void setColorOrderRGB();
+	void setColorOrderGRB();
+	void setColorOrderBRG();
+#endif
+
+private:
+	uint16_t count_led;
+	uint8_t *pixels;
+
+#ifdef RGB_ORDER_ON_RUNTIME	
+	uint8_t offsetRed;
+	uint8_t offsetGreen;
+	uint8_t offsetBlue;
+#endif	
+
+	void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask,uint8_t *port, uint8_t *portreg);
+
+	const volatile uint8_t *ws2812_port;
+	volatile uint8_t *ws2812_port_reg;
+	uint8_t pinMask; 
+};
+
+
+
+#endif /* WS2812_H_ */
diff --git a/LEDprogress/src/cRGB.h b/LEDprogress/src/cRGB.h
new file mode 100644
index 0000000..0a3f0b2
--- /dev/null
+++ b/LEDprogress/src/cRGB.h
@@ -0,0 +1,115 @@
+#ifndef CRGB_H
+#define CRGB_H
+
+/*
+Control a RGB led with Hue, Saturation and Brightness (HSB / HSV )
+
+Hue is change by an analog input.
+Brightness is changed by a fading function.
+Saturation stays constant at 255
+
+getRGB() function based on <http://www.codeproject.com/miscctrl/CPicker.asp>
+dim_curve idea by Jims
+
+created 05-01-2010 by kasperkamperman.com
+*/
+
+/*
+dim_curve 'lookup table' to compensate for the nonlinearity of human vision.
+Used in the getRGB function on saturation and brightness to make 'dimming' look more natural.
+Exponential function used to create values below :
+x from 0 - 255 : y = round(pow( 2.0, x+64/40.0) - 1)
+*/
+
+// uncomment this line if you use HSV is many projects
+// #define USE_HSV
+
+#ifdef USE_HSV
+const byte dim_curve[] = {
+	0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
+	3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+	4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
+	6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
+	8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11,
+	11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15,
+	15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20,
+	20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26,
+	27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35,
+	36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47,
+	48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+	63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82,
+	83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109,
+	110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144,
+	146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190,
+	193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255,
+};
+#endif
+
+struct cRGB { 
+	uint8_t g; 
+	uint8_t r; 
+	uint8_t b;
+
+#ifdef USE_HSV
+	void SetHSV(int hue, byte sat, byte val) {
+		/* convert hue, saturation and brightness ( HSB/HSV ) to RGB
+		The dim_curve is used only on brightness/value and on saturation (inverted).
+		This looks the most natural.
+		*/
+
+		val = dim_curve[val];
+		sat = 255 - dim_curve[255 - sat];
+
+		int base;
+
+		if (sat == 0) { // Acromatic color (gray). Hue doesn't mind.
+			r = val;
+			g = val;
+			b = val;
+		}
+		else  {
+			base = ((255 - sat) * val) >> 8;
+
+			switch (hue / 60) {
+			case 0:
+				r = val;
+				g = (((val - base)*hue) / 60) + base;
+				b = base;
+				break;
+
+			case 1:
+				r = (((val - base)*(60 - (hue % 60))) / 60) + base;
+				g = val;
+				b = base;
+				break;
+
+			case 2:
+				r = base;
+				g = val;
+				b = (((val - base)*(hue % 60)) / 60) + base;
+				break;
+
+			case 3:
+				r = base;
+				g = (((val - base)*(60 - (hue % 60))) / 60) + base;
+				b = val;
+				break;
+
+			case 4:
+				r = (((val - base)*(hue % 60)) / 60) + base;
+				g = base;
+				b = val;
+				break;
+
+			case 5:
+				r = val;
+				g = base;
+				b = (((val - base)*(60 - (hue % 60))) / 60) + base;
+				break;
+			}			
+		}
+	}
+#endif	
+};
+
+#endif
\ No newline at end of file
diff --git a/LEDprogress/src/light_ws2812.cpp b/LEDprogress/src/light_ws2812.cpp
new file mode 100644
index 0000000..2440d23
--- /dev/null
+++ b/LEDprogress/src/light_ws2812.cpp
@@ -0,0 +1,156 @@
+/*
+* light weight WS2812 lib V2.1 - Arduino support
+*
+* Controls WS2811/WS2812/WS2812B RGB-LEDs
+* Author: Tim (cpldcpu@gmail.com)
+*
+* Jan  18th, 2014  v2.0b Initial Version
+* March 7th, 2014  v2.1  Added option to retarget the port register during runtime
+*                        Removes inlining to allow compiling with c++
+*
+* License: GNU GPL v2 (see License.txt)
+*/
+
+#include "WS2812.h"
+
+/*
+  This routine writes an array of bytes with RGB values to the Dataout pin
+  using the fast 800kHz clockless WS2811/2812 protocol.
+*/
+
+// Timing in ns
+#define w_zeropulse   350
+#define w_onepulse    900
+#define w_totalperiod 1250
+
+// Fixed cycles used by the inner loop
+#define w_fixedlow    3
+#define w_fixedhigh   6
+#define w_fixedtotal  10   
+
+// Insert NOPs to match the timing, if possible
+#define w_zerocycles    (((F_CPU/1000)*w_zeropulse          )/1000000)
+#define w_onecycles     (((F_CPU/1000)*w_onepulse    +500000)/1000000)
+#define w_totalcycles   (((F_CPU/1000)*w_totalperiod +500000)/1000000)
+
+// w1 - nops between rising edge and falling edge - low
+#define w1 (w_zerocycles-w_fixedlow)
+// w2   nops between fe low and fe high
+#define w2 (w_onecycles-w_fixedhigh-w1)
+// w3   nops to complete loop
+#define w3 (w_totalcycles-w_fixedtotal-w1-w2)
+
+#if w1>0
+  #define w1_nops w1
+#else
+  #define w1_nops  0
+#endif
+
+// The only critical timing parameter is the minimum pulse length of the "0"
+// Warn or throw error if this timing can not be met with current F_CPU settings.
+#define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000)
+#if w_lowtime>550
+   #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?"
+#elif w_lowtime>450
+   #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)."
+   #warning "Please consider a higher clockspeed, if possible"
+#endif   
+
+#if w2>0
+#define w2_nops w2
+#else
+#define w2_nops  0
+#endif
+
+#if w3>0
+#define w3_nops w3
+#else
+#define w3_nops  0
+#endif
+
+#define w_nop1  "nop      \n\t"
+#define w_nop2  "rjmp .+0 \n\t"
+#define w_nop4  w_nop2 w_nop2
+#define w_nop8  w_nop4 w_nop4
+#define w_nop16 w_nop8 w_nop8
+
+void  WS2812::ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi,uint8_t *port, uint8_t *portreg)
+{
+  uint8_t curbyte,ctr,masklo;
+  uint8_t sreg_prev;
+  
+  masklo = ~maskhi & *port;
+  maskhi |= *port;
+  sreg_prev=SREG;
+  cli();  
+
+  while (datlen--) {
+    curbyte=*data++;
+    
+    asm volatile(
+    "       ldi   %0,8  \n\t"
+    "loop%=:            \n\t"
+    "       st    X,%3 \n\t"    //  '1' [02] '0' [02] - re
+#if (w1_nops&1)
+w_nop1
+#endif
+#if (w1_nops&2)
+w_nop2
+#endif
+#if (w1_nops&4)
+w_nop4
+#endif
+#if (w1_nops&8)
+w_nop8
+#endif
+#if (w1_nops&16)
+w_nop16
+#endif
+    "       sbrs  %1,7  \n\t"    //  '1' [04] '0' [03]
+    "       st    X,%4 \n\t"     //  '1' [--] '0' [05] - fe-low
+    "       lsl   %1    \n\t"    //  '1' [05] '0' [06]
+#if (w2_nops&1)
+  w_nop1
+#endif
+#if (w2_nops&2)
+  w_nop2
+#endif
+#if (w2_nops&4)
+  w_nop4
+#endif
+#if (w2_nops&8)
+  w_nop8
+#endif
+#if (w2_nops&16)
+  w_nop16 
+#endif
+    "       brcc skipone%= \n\t"    //  '1' [+1] '0' [+2] - 
+    "       st   X,%4      \n\t"    //  '1' [+3] '0' [--] - fe-high
+    "skipone%=:               "     //  '1' [+3] '0' [+2] - 
+
+#if (w3_nops&1)
+w_nop1
+#endif
+#if (w3_nops&2)
+w_nop2
+#endif
+#if (w3_nops&4)
+w_nop4
+#endif
+#if (w3_nops&8)
+w_nop8
+#endif
+#if (w3_nops&16)
+w_nop16
+#endif
+
+    "       dec   %0    \n\t"    //  '1' [+4] '0' [+3]
+    "       brne  loop%=\n\t"    //  '1' [+5] '0' [+4]
+    :	"=&d" (ctr)
+//    :	"r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo)
+    :	"r" (curbyte), "x" (port), "r" (maskhi), "r" (masklo)
+    );
+  }
+  
+  SREG=sreg_prev;
+}
diff --git a/LEDprogress/src/main.cpp b/LEDprogress/src/main.cpp
new file mode 100644
index 0000000..4316202
--- /dev/null
+++ b/LEDprogress/src/main.cpp
@@ -0,0 +1,13 @@
+#include "ofMain.h"
+#include "ofApp.h"
+
+//========================================================================
+int main( ){
+	ofSetupOpenGL(500,500,OF_WINDOW);			// <-------- setup the GL context
+
+	// this kicks off the running of my app
+	// can be OF_WINDOW or OF_FULLSCREEN
+	// pass in width and height too:
+	ofRunApp(new ofApp());
+
+}
diff --git a/LEDprogress/src/ofApp.cpp b/LEDprogress/src/ofApp.cpp
new file mode 100644
index 0000000..8afff7f
--- /dev/null
+++ b/LEDprogress/src/ofApp.cpp
@@ -0,0 +1,114 @@
+#include "ofApp.h"
+
+//--------------------------------------------------------------
+void ofApp::setup(){
+    ofEnableDepthTest();
+    
+    // Change string "/dev/somthing" to the Serial port of your arduino
+	//serial.setup("COM5", 9600);
+    arduino.connect("COM5", 57600);
+	arduino.sendFirmwareVersionRequest();
+    // Check if Arduino is ready to be setup
+    ofAddListener(arduino.EInitialized, this, &ofApp::setupArduino);
+    bSetupArduino = false;
+}
+
+//--------------------------------------------------------------
+void ofApp::setupArduino(const int & version) {
+    //Remove listener and setup arduino
+    ofRemoveListener(arduino.EInitialized, this, &ofApp::setupArduino);
+    bSetupArduino = true;
+
+    // Setup pins here! //
+    // set pin D13 as digital output for LED
+	arduino.sendDigitalPinMode(6, ARD_OUTPUT);
+   }
+
+//--------------------------------------------------------------
+void ofApp::update() {
+    //Update the arduino to get data/ messages
+    arduino.update();
+    
+    //Do not send anything until the arduino is setup
+    if(bSetupArduino){
+        //Things we are sending!
+        //Potinput = arduino.getAnalog(1);
+		//arduino.sendPwm(6, (int)(128 + 128 * sin(ofGetElapsedTimef())));
+      
+    }
+
+    
+}
+
+//--------------------------------------------------------------
+void ofApp::draw(){
+    ofBackground(255);
+    
+    displayArduinoData();
+  
+
+    
+
+}
+
+//--------------------------------------------------------------
+void ofApp::displayArduinoData() {
+    
+    ofSetColor(0, 0, 0);
+    if(!bSetupArduino){
+        ofDrawBitmapString("not ready...\n", 100, 50);
+    } else {
+        ofDrawBitmapString("ready", 100, 50);
+        // print input values etc.
+          }
+}
+
+//--------------------------------------------------------------
+void ofApp::keyPressed(int key) {
+	if (bSetupArduino) {
+		if (key == '1') {
+			//arduino.sendByte(3);
+			arduino.sendByte(0);
+			arduino.sendByte(0);
+			arduino.sendByte(0);
+			arduino.sendDigital(6, 1);
+			//arduino.sendByte(1);
+			//arduino.sendPwm(6, (int)(128 + 128 * sin(ofGetElapsedTimef())));
+			
+		}
+		
+            // turn led on here
+   
+    }
+}
+
+//--------------------------------------------------------------
+void ofApp::keyReleased(int key){
+    if(bSetupArduino) {
+        if (key == '1'){
+            // turn led off here
+              arduino.sendDigital(6, 0);
+		
+        }
+    }
+}
+
+//--------------------------------------------------------------
+void ofApp::mouseMoved(int x, int y ){
+
+}
+
+//--------------------------------------------------------------
+void ofApp::mouseDragged(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void ofApp::mousePressed(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void ofApp::mouseReleased(int x, int y, int button){
+
+}
diff --git a/LEDprogress/src/ofApp.h b/LEDprogress/src/ofApp.h
new file mode 100644
index 0000000..e522188
--- /dev/null
+++ b/LEDprogress/src/ofApp.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "ofMain.h"
+#include "ofEvents.h"
+
+class ofApp : public ofBaseApp{
+
+	public:
+		void setup();
+		void update();
+		void draw();
+
+		void keyPressed(int key);
+		void keyReleased(int key);
+		void mouseMoved(int x, int y );
+		void mouseDragged(int x, int y, int button);
+		void mousePressed(int x, int y, int button);
+		void mouseReleased(int x, int y, int button);
+    
+        void setupArduino(const int & version);
+    
+        void displayArduinoData();
+    
+        int Potinput;
+    
+    
+
+    
+    private:
+        ofArduino	arduino;
+        bool bSetupArduino;
+    
+      
+       };
-- 
GitLab