Navigation

    • Register
    • Login
    • Search
    • OpenHardware.io
    • Categories
    • Recent
    • Tags
    • Popular
    1. Home
    2. AWI
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    AWI

    @AWI

    Hero Member

    505
    Reputation
    1155
    Posts
    4692
    Profile views
    14
    Followers
    1
    Following
    Joined Last Online
    Website http:// Location Netherlands

    AWI Follow
    Mod Hardware Contributor Hero Member

    Best posts made by AWI

    • Double Micro (nano) Ampere meter

      A very low current (double) stand alone uA meter to tune MySensors battery nodes..
      0_1493111992919_upload-0091f8f7-8b1a-4d26-8c5d-f66cffe3408c
      I de' MySensor'ized this project because it is more usefull on the workbench for measuring the very low currents of MySensors battery nodes. I own several Ampere meters including the famous µCurrent. Many of these are not accurate enough or need a lot of wiring and additional equipment (µCurrent). I just wanted something simple and stand alone
      Using the low cost HX711 weight scale 24 bit AD converter a sub 10€ cost double µA meter was born. Some characteristics to fit MySensors projects:

      • range channel A: ± 20mA 5½-6½ digit µA
      • range channel B: ±40mA 5½-6½ digit µA
      • burden voltage 1µV/1µA (internal resistance 1Ω)
      • 'patch panel' on the connectors.
      • easy calibration.

      In comparison with the µCurrent and a standard multimeter in uA range
      0_1493113275783_upload-2a33c4be-759a-46c6-af8f-57862ecf4e3c

      The internals:
      0_1493113146906_upload-9152b445-76e8-44e6-8625-530f33a80d20

      Although it cannot compare in accuracy with the µCurrent (in combination with a good multimeter) it is more than useable and accurate to do some serious MySensors tuning.

      If there is some interest I will try to publish a decent built instruction on Openhardware.io.

      posted in My Project
      AWI
      AWI
    • nRf24L01+ connection quality meter

      A little frustrated by radio's showing inconsistent behaviour I built a simple connection quality meter with a leftover of a previous project.

      0_1464549715094_upload-8cefcb84-2528-42e3-98e1-792b63fc0b50

      Not too complicated 😉 a nano, I2C lcd display, radio adapter board (guarantees a stable power supply for the radio) and the radio to be tested.

      0_1464549601260_upload-0bca4a04-80b0-4f70-9263-cef5d75e7702

      a little hot glue and it fits nicely in the box. The radio can be swapped on the outside. Power comes in from a power bank connected to the nano USB so that I can walk around the house.

      0_1464549797943_upload-328cbdd6-bd88-417c-9bbb-0160b1a2d55a

      The sketch sends values from 0..99 to a gateway with "ack" enabled. The LCD shows the "failed" sends and the number of not acknowledged messages. i.e. the messages which did not arrive at the gateway or did not make it on their return flight.

      It now takes less than a minute to sort the radio's :bowtie:

      posted in My Project
      AWI
      AWI
    • Wall mounted 'mood light'

      (there is a sketch for MySensors v2 available)
      I received my 110v-230v AC to Mysensors PCB board last week en spent a few hours this weekend making 2 wall mounted mood lights.
      upload-12d13e93-9d8f-4244-b1a4-2e74d014587c

      I looks a little cheap from the backside but very luxurious on the wall ( < €20 total) and fully "MySensored".

      upload-cbbe7065-68b3-4108-b6c1-ebffc7cbdddb

      I did not use the relais on the board (and discarded some of the safety measures 😊 ). Very basic: a cut WS2812b strip, a few wires.
      Case is 12 mm MDF Board painted with Chalk paint (no primer needed, ready in half an hour ;-))

      Basic sketch with FastLED library (or Adafruit) with V_RBG.

      upload-1c215841-3f7f-4e6a-a856-f8d6f6435818

      upload-c7e90b81-b8b1-46b8-843d-b8c8007cd521 upload-1b906742-96fc-4b41-a24e-6fa302921d10

      posted in My Project
      AWI
      AWI
    • "Weathercock" / weather comfort station

      0_1462545364186_upload-42f07aaa-ce36-4d9a-8758-c0f43003456d

      I couldn't wait to share my latest project... The weather is getting better and I wanted to have a simple display (and later on a more ' techie' one) to display if it is comfortable to go outside. The rooster (and ring) show the wind direction and the rest of the leds show if anything is in range. green == comfortable ; red == extreme (for my standards) but it smoothly displays all the colors in between (rainbow).

      Another (soon to be published) project I am working on is a solar powered weather sensor station with alternative wind sensor.. At this stage I am getting data from the controller (Domoticz) in a kind of proprietary V_TEXT form.

      The final version will get it's data directy from a MySensors sensor station... and a better crafted rooster. 😊

      A beginners project.. Main components: stepper with driver ; WS2812 8 led ring & 5 separate leds and a MySensors arduino node (JModule in this case). All powered by a 5V usb supply.
      0_1462546054383_upload-df75e5d1-7600-4b72-8a12-29adea470c7f

      If anyone is interested I will publish the details on openhardware.

      Doing the startup animation to show it's capabilities..

      WeatherCock MySensors – 00:42
      — Ad Imhoff

      0_1462545448665_upload-df1a6b48-7c5c-4986-8378-fef9aedd33d1

      posted in My Project
      AWI
      AWI
    • Wall mounted 'mood light' v2

      I made a few changes to my Wall mounted 'mood light' and translated it to MySensors v2.
      0_1474615675050_upload-71b7410c-eae1-43a3-abf8-d074aff5058a

      The sketch shows an example of using a Domoticz selector switch attached to a dimmer (V_PERCENTAGE) to switch between the different light patterns (line 413). I'm pretty sure you can use this trick for more controllers.
      0_1474615943349_upload-f05ed149-c991-4e54-84df-ef1585d32ed9

      /*
       PROJECT: MySensors / RGB light NEOPIXEL
       PROGRAMMER: AWI
       DATE: october 10, 2015/ last update: september 20, 2016
       FILE: AWI_Wall_LIght_x.ino
       LICENSE: Public domain
      
       Hardware: Nano and MySensors 2.0, Wall light 16 WS2812B leds (neopixel)
      		
       Special:
      	uses Fastled library with NeoPixel (great & fast RBG/HSV universal library) 			https://github.com/FastLED/FastLED
      	
       SUMMARY:
      	
      	Different patterns and brightness settings
      	
      	Button switches on/off and cycles through all Color patterns on long press
      	
       Remarks:
      	Fixed node-id
      	
       Change log:
       20160915 - Updated to MySensors 2.0
       20160920 - Changed state change to dimmer i.s.o. switch()
      
      */
      //****  MySensors *****
      // Enable debug prints to serial monitor
      #define MY_DEBUG 
      #define MY_RADIO_NRF24										// Enable and select radio type attached
      //#define MY_RF24_CHANNEL 80								// radio channel, default = 76
      
      #define MY_NODE_ID 62
      #define NODE_TXT "W 62"										// Text to add to sensor name
      
      // #define MY_RF24_CE_PIN 7									// Ceech board, 3.3v (7,8)  (pin default 9,10)
      // #define MY_RF24_CS_PIN 8
      
      // helpers
      #define LOCAL_DEBUG											// enable if print wanted 
      
      #ifdef LOCAL_DEBUG
      #define Sprint(a) (Serial.print(a))							// macro as substitute for print, enable if no print wanted
      #define Sprintln(a) (Serial.println(a))						// macro as substitute for println
      #else
      #define Sprint(a)										
      #define Sprintln(a)
      #endif
      
      
      
      #include <SPI.h>											// My Sensors
      #include <MySensors.h>
      
      #include <FastLED.h>										// https://github.com/FastLED/FastLED
      #include "Button.h"											// https://github.com/JChristensen/Button
      
      const int stripPin = 5 ;									// pin where 2812 LED strip is connected
      const int buttonPin = 4 ;									// push button
      const int numPixel = 16 ;									// set to number of pixels (x top / y bottom)
      
      const int RGB_LightChild = 0 ;								// Child Id's, standard light child on/off/ dim
      const int RGB_RGBChild = 1 ;								// RGB light child (on/off/dim/color, if controller supports V_RBG))
      const int RGB_SolidColorChild = 2 ;							// when set, node reads Color text from ColorTextChild
      const int RGB_TextColorChild = 3 ;							// Holds Text value for color (custom colors from controller)
      const int RGB_AlarmPatternChild = 4 ;						// Switches to alarm status
      const int RGB_NextPatternChild = 5 ;						// Move to next pattern when set
      
      CRGB leds[numPixel];
      
      // Kelving colors: Light & daylight (in Fastled reference only)
      /// 1900 Kelvin Candle=0xFF9329 /* 1900 K, 255, 147, 41 */,
      /// 2600 Kelvin Tungsten40W=0xFFC58F /* 2600 K, 255, 197, 143 */,
      /// 2850 Kelvin Tungsten100W=0xFFD6AA /* 2850 K, 255, 214, 170 */,
      /// 3200 Kelvin	Halogen=0xFFF1E0 /* 3200 K, 255, 241, 224 */,
      /// 5200 Kelvin CarbonArc=0xFFFAF4 /* 5200 K, 255, 250, 244 */,
      /// 5400 Kelvin HighNoonSun=0xFFFFFB /* 5400 K, 255, 255, 251 */,
      /// 6000 Kelvin DirectSunlight=0xFFFFFF /* 6000 K, 255, 255, 255 */,
      /// 7000 Kelvin OvercastSky=0xC9E2FF /* 7000 K, 201, 226, 255 */,
      /// 20000 Kelvin ClearBlueSky=0x409CFF /* 20000 K, 64, 156, 255 */
      
      char setRGBvalue[] = "FFC58F";		 						// Controller sent RGB value, default tungsten40W
      uint16_t curBrightness = 0x7F, setBrightness = 0x7F ;		// Brightness globals (actualBrightness)
      unsigned long updateBrightnessDelay, lastBrightnessUpdate ; // Brightness timers
      int RGBonoff ;												// OnOff flag
      
      enum { pSolid, pOff, pOn, pAlarm, pFire, pFire2, pCandle, pCircle, pSinelon, pRainbow}  ;	// Pattern states (stored in int for convenience)
      const int lastPatternIdx = pRainbow + 1 ;					// use last pattern for patterncount
      int curPattern = pSolid ;									// current pattern
      int setPattern = pSolid ;									// set pattern (controller)
      unsigned long updatePatternDelay, lastPatternUpdate ;		// Pattern timers
      
      unsigned long idleTimer = millis() ;						// return to idle timer
      const unsigned long idleTime = 10000UL;					// return to idle after 10 secs
      
      const unsigned long dimTime = 1000UL;						// dim period
      
      const unsigned long heartbeatInterval = 1 * 60UL * 1000UL ;	// heartbeatinterval, just to let the controller know I am alive
      unsigned long heartbeatCounter = 0 ;
      
      MyMessage lightRGBMsg(RGB_LightChild,  V_RGB);				// standard messages, light
      MyMessage lightdimmerMsG(RGB_LightChild ,V_DIMMER);	
      MyMessage lightOnOffMessage(RGB_LightChild, V_STATUS);
      
      Button myBtn(buttonPin, true, true, 20);					//Declare the button (pin, pull_up, invert, debounce_ms)
      
      // Simple state machine for button state
      enum {sIdle, sBrightness, sPattern} ;						 // simple state machine for button press
      int State ;
      
      void setup() {
      	FastLED.addLeds<WS2812B, stripPin, GRB >(leds, numPixel); 	// initialize led strip (NEOPIXEL =WS...)
      	for(int i = 0 ; i < 6 ; i++) {							// get color value from EEPROM (6 char)
      		setRGBvalue[i] = loadState(i) ;
      		}
      	setLightPattern(pSolid, 0) ;							// default controller Solid 
      	FastLED.show();
      	State = sIdle ;											// Initial state
      	//randomSeed(analogRead(0));
      }
      
      
      
      void presentation(){
      // MySensors
      	sendSketchInfo("AWI RGB Wall " NODE_TXT, "2.0");
      	present(RGB_RGBChild, S_RGB_LIGHT, "RGB Wall RGB " NODE_TXT);// present to controller
      	present(RGB_LightChild, S_LIGHT, "RGB Wall Light " NODE_TXT);
      	present(RGB_SolidColorChild, S_LIGHT, "RGB Set Solid color (text) " NODE_TXT);
      	present(RGB_TextColorChild, S_INFO, "RGB Wall textcolor " NODE_TXT);	
      	present(RGB_AlarmPatternChild, S_BINARY, "RGB Wall Alarm " NODE_TXT);
      	present(RGB_NextPatternChild, S_DIMMER, "RGB Wall Pattern " NODE_TXT);
      }
      
      
      
      // read button and act accordingly
      // short press: on/off
      // longer press: set patterns with following short press
      // long press: set brightness increase 
      void loop() {
      	myBtn.read();               							//Read the button (only read)
      	unsigned long now = millis(); 							// loop timer reference
      	switch (State) {
      		case sIdle:											// default state, browse through patterns
      			if (myBtn.wasReleased()){						// light on/ off in idle
      				RGBonoff = !RGBonoff ;						// invert light state
      				setLightBrightness((RGBonoff == 1)?setBrightness:0, dimTime);
      				send(lightOnOffMessage.set(RGBonoff));	// and update controller	
      			} else if (myBtn.pressedFor(800)){				// move to Pattern update state with long press
      				idleTimer = now ;							// return to idle after ...
      				State = sPattern ;
      			}
      			break ;
      		case sPattern:										// entered after long press
      			if (myBtn.pressedFor(4000)){					// when press even longer move to Brightness update
      				State = sBrightness ;
      			} else if (myBtn.wasPressed()){
      				setPattern = (setPattern + 1) % lastPatternIdx ;  // increase pattern and wrap
      				setLightPattern((setPattern), 500 );
      				idleTimer = now ;
      			} else if ( now > idleTime + idleTimer  ){		// return to idle after ...
      				State = sIdle ;
      			}
      			break ;
      		case sBrightness:									// entered after looong press
      			if (myBtn.wasPressed()){							// if pressed again increase brightness
      				setLightBrightness((curBrightness+0x1F) % 0xFF, 0) ; // increase brightness and wrap (0..0xFF)
      				idleTimer = now ;
      			} else if ( now > idleTime + idleTimer  ){		// return to idle after ...
      				State = sIdle ;
      			}
      			break ;
      		default :
      			State = sIdle ;
      			break ;
      		}
      	updateLightBrightness();								// update Brightness if time
      	updateLightPattern();									// update Pattern if time
      	if ( now > heartbeatCounter  + heartbeatInterval){		// heartbeat every hour
      	    sendHeartbeat();
      		heartbeatCounter = now ; 
      		}
      	}
      
      // Sets the light brightness, takes value and time (ms) as input
      void setLightBrightness(int newBrightness, unsigned long updateTime){
      	// global: curBrightness, actualBrightness, updateBrightnessDelay
      	updateBrightnessDelay = updateTime / 0xFF ;				// delay = time / max steps
      	curBrightness = newBrightness ;							// set curBrightness to new value, rest is done in update
      	}	
       
      // Update the light brightness if time
      void updateLightBrightness(){
      	// global: curBrightness, actualBrightness, updateBrightnessDelay, lastBrightnessUpdate ;
      	static byte actualBrightness ;							// store real brightness state for slow dim
      	unsigned long now = millis() ;
      	if (now > lastBrightnessUpdate + updateBrightnessDelay){// check if time for update
      		if ( actualBrightness > curBrightness) {
      			FastLED.setBrightness( actualBrightness-- );
      			FastLED.show();
      		} else if ( actualBrightness < curBrightness){
      			FastLED.setBrightness( actualBrightness++ );
      			FastLED.show();
      			}
      		lastBrightnessUpdate = now ;
      		}
      	}
      
      // **** Pattern routines *****
      // Sets and initializes the light pattern if nescessary
      void setLightPattern( int newPattern, unsigned long updateDelay){
      	// global: curPattern, updatePatternDelay
      	static int lastPattern = pSolid ;						// last pattern for pOn / pOff virtual patterns
      	if (newPattern == pOff) lastPattern = curPattern ;		// remember last pattern
      	if (newPattern == pOn) curPattern = lastPattern ;		// only for pOn switch to last pattern
      	else curPattern = newPattern ;
      	updatePatternDelay = updateDelay ;						// delay for next pattern update, can be changed in pattern 
      	switch(curPattern){
      		case pSolid:										//  solid is set value in all pixels (and on)
      			for(int i = 0 ; i < numPixel ; i++) leds[i] = strtol( setRGBvalue, NULL, 16);
      			setLightBrightness(setBrightness, dimTime) ;	// slow dim to on
      			FastLED.show();
      			break ;
      		case pOn:											//  On is set Brightness in all pixels
      			setLightBrightness(setBrightness, dimTime) ;		// slow dim to on
      			FastLED.show();
      			break ;
      		case pOff:											//  off state all pixels off (add dim and pOn)
      			setLightBrightness(0, dimTime) ; 					// slow dim to off
      			FastLED.show();
      			break ;
      		case pCircle:										//  all pixels off
      			for(int i = 0 ; i < numPixel ; i++) leds[i] = 0 ;
      			for(int i = 0 ; i < 2 ; i++){
      				leds[i] = strtol( setRGBvalue, NULL, 16) ; // 1 pixel on
      				}
      			FastLED.show();
      			break ;
      		default :
      			setLightBrightness(setBrightness, dimTime) ;	// slow dim to on
      			FastLED.show();
      			break ;
      			}
      	}	
      
      // Update the light pattern when time for it
      void updateLightPattern(){
      	// global: curPattern, updatePatternDelay, lastPatternUpdate
      	unsigned long now = millis() ;
      	if (now > lastPatternUpdate + updatePatternDelay){		// check if time for update
      		switch (curPattern) {
      			case pAlarm:									// flash light
      				patternAlarm();
      				break ;
      			case pFire:										// wild fire
      				patternFire();
      				break ;
      			case pFire2:									// cosy fire
      				patternFire2();
      				break ;
      			case pCandle:									// flame
      				patternCandle();
      				break ;
      			case pCircle:									// flame
      				patternCircle();
      				break ;
      			case pRainbow:									// rotating rainbow
      				patternRainbow();
      				break ;
      			case pSinelon:									// rotating rainbow
      				patternSinelon();
      				break ;
      			case pSolid:									// do nothing fall through
      			case pOff:
      			case pOn:
      			default	:										// def	
      				break ;
      			}
      		lastPatternUpdate = now ;
      		}
      	}
      
      // Define the different patterns
      // Alarm - intermittent white and red color, full intensity, intermittent top & bottom half
      void patternAlarm() {
          static boolean topBot ;									// indicates direction for next entry
      	const CRGB colorTop = CRGB(0xFF, 0, 0 );				// red color
      	const CRGB colorBottom = CRGB(0xFF, 0xFF, 0xFF );		// white color
      	FastLED.setBrightness(0xFF);							// set the strip brightness to max for Alarm
      	for(int i=0; i <= (numPixel / 2 - 1) ; i++) {			// for half of strip size
      		leds[i] = topBot?colorTop:colorBottom ;	
      		leds[i+ (numPixel/2)] = topBot?colorBottom:colorTop ;
      		}
      	topBot = !topBot ;										// switch direction
      	FastLED.show();
      	}
      
      // Simulate fire with red color, varying number of leds intensity & tempo
      void patternFire() {
          byte numberLeds = random(0,numPixel);					// start number and end of led's for flickering
          int lum = ((random(100,255) * curBrightness)) / 0xFF ;	// set brightness and scale
          CRGB color = CRGB(200, random(70,230),0 );				// get red color with varying green
          for(int i=0; i <= numberLeds; i++) {
            leds[i] = color ;
            FastLED.setBrightness(lum);							// set the strip brightness
            FastLED.show();
            wait(random(0,10));									// (blocking, need to be changed)
          }
          updatePatternDelay = 100 ; 
      }
      
      // Simulate fire with red color and varying intensity & tempo
      void patternFire2() {
          CRGB color = CRGB(200, random(100,150),0);				// get red color with varying green
          for (byte p=0; p < numPixel; p++) {
            leds[p] = color;
          }
          FastLED.setBrightness((random(50,255) * curBrightness)/ 0xFF );	// set Brightness and scale
          FastLED.show();
          updatePatternDelay = random(20,300);					// variable delay
      }
      
      // Simulate candle based on fire with red color, varying number of leds intensity & tempo
      void patternCandle() {
          byte numberLeds = random(0,numPixel);					// start number and end of led's for flickering
          byte lum = ((random(100, 255) * curBrightness)/ 0xFF);	// set brightness
          CRGB color = CRGB(200, random(90,130),0 );				// get red color with varying green
          for(int i=0; i <= numberLeds; i++) {
            leds[i] = color ;
            FastLED.setBrightness(lum);							// set the strip brightness
            FastLED.show();
            wait(random(5,10));									// (blocking, need to be changed)
          }
          updatePatternDelay = 100 ; 
      }
      
      // a colored dot sweeping back and forth, with fading trails, adapted from Fastled sinelon
      void patternSinelon()
      {
      	fadeToBlackBy( leds, numPixel, 10);						// fade all leds a small amount 
      	int pos = beatsin8(25,0,numPixel);						// get a new position for the led (BPM = 13, min, max, )
      	leds[pos] += strtol( setRGBvalue, NULL, 16);
      	FastLED.show();
      	updatePatternDelay = 2 ;
      }
      
      
      // Rotate all Leds with current content and trail
      void patternCircle() {
      	static int currentLed ;									// indicated current led to light
      	// CRGB tempLed = leds[0];					 			// temporary variable for color
      	fadeToBlackBy( leds, numPixel, 128);					// fade all leds for trail..
      	leds[currentLed] = strtol( setRGBvalue, NULL, 16);		// set to current color
      	currentLed = (currentLed + 1) % numPixel ;				// wrap
          FastLED.show();
          updatePatternDelay = 100 ; 
      }
      
      void patternRainbow() {
      	static uint16_t hue ;									// starting color
      	FastLED.clear();
      	// for(hue=10; hue<255*3; hue++) {
      	hue = (hue+1) % 0xFF ;									// incerease hue and wrap
      	fill_rainbow( leds, numPixel , hue /*static hue value */, 1);// set a rainbow from hue to last in stepsize 1
      	FastLED.show();
      	updatePatternDelay = 100 ;
      	}
      
      // Incoming messages from MySensors
      void receive(const MyMessage &message) {
      	int ID = message.sensor;
      	Serial.print("Sensor: ");
      	Serial.println(ID);
      	switch (ID){
      		case RGB_LightChild:								// same behaviour as RGB child/ fall through
      		case RGB_RGBChild:									// if controller can handle V_RGB
      			if (message.type == V_RGB) {					// check for RGB type
      				strcpy(setRGBvalue, message.getString());	// get the payload
      				setLightPattern(pSolid, 0);					// and set solid pattern 
      			} else if (message.type == V_DIMMER) {			// if DIMMER type, adjust brightness
      				setBrightness = map(message.getInt(), 0, 100, 0, 255);
      				setLightBrightness(setBrightness, dimTime) ;
      			} else if (message.type == V_STATUS) {			// if on/off type, toggle brightness
      				RGBonoff = message.getInt();
      				setLightBrightness((RGBonoff == 1)?setBrightness:0, dimTime);
      			}
      			break ;
      		case RGB_SolidColorChild:							// request color from controller
      			if (message.type == V_STATUS) {					// if get color from text child
      				request(RGB_TextColorChild, V_TEXT);
      				setLightPattern(pSolid, 0);					// and set solid pattern (if not alre)
      				}
      			break ;
      		case RGB_TextColorChild:							// Text color from controller
      			if (message.type == V_TEXT) {					// if get color from text child
      				strcpy(setRGBvalue, message.getString());	// get the payload
      				for(int i = 0 ; i < 6 ; i++) {				// save color value to EEPROM (6 char)
      					saveState(i, setRGBvalue[i]) ;}			// Save to EEPROM
      				}
      			break ;
      		case RGB_AlarmPatternChild:							// set Alarm pattern
      			if (message.type == V_STATUS) {					// if get color from text child
      				if (message.getInt() == 1){
      					setLightPattern(pAlarm, 500);			// set slow alarm pattern
      				} else {
      					setLightPattern(setPattern, 0);			// and reset pattern
      					FastLED.setBrightness(setBrightness);
      					}
      				}
      			break ;
      		case RGB_NextPatternChild:							// next pattern
      			if (message.type == V_PERCENTAGE) {				//  Percentage indicates the pattern
      				setPattern = map(message.getInt(), 0, 100, 0, 15) % lastPatternIdx  ; // mapper dimmer value to state 0..9  and wrap
      				setLightPattern((setPattern), 500 );
      				Sprint("Pattern: ") ; Sprintln(setPattern) ;
      			} else if (message.type == V_STATUS){			// if off switch pattern to default == 0
      				setPattern = 0  ;
      				setLightPattern((setPattern), 500 );
      				Sprint("Pattern: ") ; Sprintln(setPattern) ;
      			}
      			break ;
      		}
          FastLED.show();
      	dispRGBstat();
       	}
      // debug	
      // display the status of all RGB: controller, requested, real
      void dispRGBstat(void){
          Serial.print(" Color: "); Serial.print(setRGBvalue); 
          Serial.print(" Brightness: "); Serial.println(setBrightness);
      	}
      
      
      posted in My Project
      AWI
      AWI
    • Using the "Selector switch" in Domoticz (tutorial)

      Domoticz features a special switch type named "Selector switch" . This switch type can serve many MySensors purposes. In this walk through it is used for selecting different light patterns in my Wall mounted 'mood light'.
      A "button set"
      0_1474613749068_upload-5c2bdf83-e135-4b01-a842-f8bf16b2c468

      or "select menu"
      0_1474613812167_upload-ff85302a-8b41-4033-8654-f3d85a0a2351

      Essentially it is (or can be) a switch which controls another device. In this case I use it to control a dimmer. Let's start.

      1. Create a virtual hardware device (if you have not already done so before)

      0_1474614096927_upload-fdbc81ca-84db-4f95-8a4c-36d9434bde72

      1. Create a new "Virtual Sensor" with type "Selector Switch" by pressing the "Create Virtual Sensors" button.
        0_1474614259118_upload-dfadaa31-681c-4100-9f65-7e9b77705850
        you can also use the "Manual Light/Switch" button in the "Switches" tab.
        0_1474614203400_upload-fc866b82-9544-43ac-ad46-280721ae59eb

      This will create a new Virtual selector switch.
      0_1474614396110_upload-9189aef8-4502-43ce-bbb5-386dc84d6cb1

      I will use this to control a dimmer device which output is used to set the light patterns in the mood light
      0_1474614481046_upload-803f08fb-dda1-4142-8677-d9fb706ad9bd

      1. In the devices tab find the "Dimmer you want the Selector attached to (in this case RGB Wall Pattern W 62" with index 971
        0_1474614623251_upload-a4eb98fa-e59f-4915-a4aa-a970f8ab57c6

      "Edit" the newly created Selector switch and for each of the selector states attach a command to be executed.

      The commands here can be pretty much anything but here I used the Domoticz JSON command to set the Dimmer to one of the 16 possible states (Yes, a dimmer can only asume 16 states). You need to put your own domoticz URL/IP and port number in there. "Idx" is the dimmer device index from the previous step.

      A maximum of 10 switch values can be assigned
      ❗ don't forget to save 😓

      0_1474614939249_upload-825741bf-c2ee-4538-ad15-7881f12fc4ca
      I deliberately did not set "level 1" , because this translates to "0" and is associated with the off state in my case (room light)

      for the copycats (don't forget to include your own values):

      http://192.168.2.110:8080/json.htm?type=command&param=switchlight&idx=971&switchcmd=Set%20Level&level=0
      

      That's it. Now when you press a selector button it switches the dimmer value.

      In your sketch you can translate the dimmer values to differenct actions. Have a look at the Wall light sketch for an example.

      posted in Domoticz
      AWI
      AWI
    • USB ISP programmer with Small AA sensor node

      Programming a bare ATMEGA can be quite cumbersome. Using a cheap USB ISP programmer and the Arduino IDE simplifies things.

      0_1456997858419_upload-6532ca59-67fd-4ee5-a524-206a11ab024c

      I equipped The multi purpose Slim 2AA Battery Node with a ZIF socket and resonator (only needed if the bare ATMEGA328 is pre programmed to need an external crystal) and voila: a €6 USB ISP programmer for your MySensors nodes!

      0_1456998326251_upload-309e3269-313f-42dc-9139-0731e45111c7
      0_1456997605485_upload-9a7eedf6-d78e-4c14-ad63-02b624761a87

      (notice that I mounted the components on the back side of the board, in fact most are not actually needed)

      Select the right programmer in the Arduino IDE and you can set fuses and upload you preferred bootloader.

      posted in My Project
      AWI
      AWI
    • Remote debug messages with V_TEXT

      Sometimes I want to have debug information from my nodes while these are not connected through serial. I.e. to discover "random" freezes of an outside weather node. So I rewrote a familiar macro

      #define LOCAL_DEBUG
      #ifdef LOCAL_DEBUG
      	#define Sprint(a) (Serial.print(a))						// macro as substitute for print, enable if no print wanted
      	#define Sprintln(a) (Serial.println(a))					// macro as substitute for println
      #else														// no print
      	#define Sprint(a)
      	#define Sprintln(a)
      #endif
      

      to include "remote debugging" by using "sprintf()" (formatted print). It is a (working) first attempt with limitations. Suggestions for improvement are more than welcome. The debug information is sent with V_TEXT and needs to be handled by the controller or a "logging node" (I will publish one soon)

      // Helper for Debug:  1 = Serial debug output ; 2 = V_TEXT remote output ; else no debug
      // Use Formats described in fprint() : http://www.cplusplus.com/reference/cstdio/printf/  
      // Example: 	Printf("Temp %2d Hum %2d\n", temperature, humidity);
      // warning: max print size < 24 ; float = NOT supported in Arduino, you need to convert it yourself, ie. dtostrf(Temperature, 5, 2, tempBuf)
      #define _DEBUG 2												// 0 = no output ; 1 = Serial debug output ; 2 = V_TEXT remote output 
      #if _DEBUG == 1													// Serial output
      	char printBuf[24] ;											// need temporary buffer
      	#define Printf(...) { sprintf(printBuf, __VA_ARGS__) ; Serial.print(printBuf);}	// macro to substitute Printf()
      #elif _DEBUG == 2												// if remote debug you need to define a child and present it to the controller
      	#define DEBUG_CHILD_ID 10									// Child id of V_TEXT
      	MyMessage debugMsg(DEBUG_CHILD_ID, V_TEXT);					// get the debug message ready
      	char printBuf[24] ;											// need temporary buffer
      	#define Printf(...) { sprintf(printBuf, __VA_ARGS__) ; send(debugMsg.set(printBuf)); }	// macro to substitute Printf()						
      #else															// No debug wanted
      	#define Printf(...)										
      #endif
      
      posted in Development
      AWI
      AWI
    • Scrolling Text sensor node with new V_TEXT

      Another experiment for the V_TEXT variable/ sensor. Including brightness & speed setting and special Alarm function.
      upload-3aa973f9-d6cf-41a5-8b59-2241311896b0
      A scrolling display to let the family now that the dog needs walking... nothing more than 1 nano, 8 (or whatever number) of displays with max7219 controller upload-f2290f64-a15d-48c9-8420-ab65e481a492 a radio and a few cables
      upload-4c163020-edac-4bc5-b3bf-50f1f3cccd24
      Total cost: €18 (with 8 displays)

      in Domoticz:
      upload-868a0c0c-a44d-480f-940c-e0378716ebd3
      Built around the very versatile "Parola" driver library

      (I will upload a video when I know how to .. ;-))
      MySensors - Scrolling text display – 00:05
      — Ad Imhoff

      /*
       PROJECT: MySensors / Scrolling Text display
       PROGRAMMER: AWI
       DATE: september 12, 2015/ last update: september 12, 2015
       FILE: AWI_scroll_MAX.ino
       LICENSE: Public domain
      
       Hardware: tbd ..Ceech - ATmega328p board w/ NRF24l01
      	and MySensors 1.5 ()
      		
      Special:
      	Need to use MySensors development edition 
      	
      SUMMARY:
      	3 S_xx devices for scrolling text
      	- Displays a scrolling text from a "V_TEXT" variable
       	- additional dimmer sensor for controlling display brightness
      	- 'Alarm' switch. If "On", overrides the text display to display ALARM message
      	- You can also input messages from the Serial monitor (testing)
      	Uses excellent MD_MAX72XX library 
       Remarks:
      	Fixed node-id
      */
      
      // Use the MD_MAX72XX library to scroll text on the display with the use of the callback function 
      // to control what is scrolled on the display text.
      // You need to set the used display in the library MD_MAX72XX.h
      // User can enter text on the serial monitor and this will display as a
      // Speed for the display is controlled by a pot on SPEED_IN analog in.
      #include <MD_MAX72xx.h>						// multipurpose library for MAX72xx diaplay driver  https://parola.codeplex.com/
      #include <MySensor.h>          				// Mysensor network
      #include <SPI.h>
      #include <Time.h>   						//http://playground.arduino.cc/Code/Time
      #define	USE_POT_CONTROL	0					// enable Scroll speed  potentiometer
      #define	PRINT_CALLBACK	0
      
      // Macro to simplify serial print
      #define	PRINT(s, v)	{ Serial.print(F(s)); Serial.print(v); }
      
      // Define the number of devices we have in the chain and the hardware interface
      // need to be adapted to your setup
      const int MAX_DEVICES = 8 ;					// number of 8x8 displays
      const int CLK_PIN = 7 ; 					// SPI like clock
      const int DATA_PIN = 8 ;					// SPI like data
      const int CS_PIN = 6 ; 						// SPI like select
      
      // Parola is able to use SPI hardware interface, not testted in combination with MySensors
      // MD_MAX72XX mx = MD_MAX72XX(CS_PIN, MAX_DEVICES);
      // now use Arbitrary pins
      MD_MAX72XX mx = MD_MAX72XX(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);	// instantiate one display chain
      
      // Scrolling parameters, you can attach normal potentiometer to A5, Vcc, Gnd
      #if USE_POT_CONTROL
      const int SPEED_IN = A5 ;
      #else
      const int SCROLL_DELAY = 20 ;				// in milliseconds
      #endif // USE_POT_CONTROL
      
      const int CHAR_SPACING = 1 ;				// pixels between characters
      
      // MySensors constants & variables
      const byte nodeId = 51 ;					// MySensors fixed node id
      const byte messageCHILD = 8 ;				// Text from ControllerLCD
      const byte brightnessChild = 9 ;			// Brightness of display
      const byte alarmChild = 10 ;				// Display Alarm text (overrides normal text)
      boolean timeReceived = false ;				// Flag to indicate time received
      // Display constants & variables
      byte textBrightness = 1 ;					// brightness of display (between 0 - MAX_INTENSITY (0xF)
      byte textOnOff = true ;						// textOnOff = ! shutdown
      boolean textAlarm = false ;					// Alarm (switch S_BINARY)
      // Global message buffers shared by MySensors and Scrolling functions
      const int BUF_SIZE = 25 ;					// max payload for MySensors(NRF24l01)
      char curMessage[BUF_SIZE];					// current displayed message
      char newMessage[BUF_SIZE];					// next message to be displayed if available
      bool newMessageAvailable = false ;			// new message available flag
      uint16_t	scrollDelay;					// in milliseconds
      
      // *** Definition and initialisation
      // define the MySensor network (1.5)
      MyTransportNRF24 transport(9,10); 			// Sensoduino (8,7) Ceech board, 3.3v (7,8)  (pin default 9,10)
      MySensor gw(transport);  
      // Initialize messages for sensor network
      MyMessage textMsg(messageCHILD, V_TEXT);	// message for Sending Text to Controller
      
      
      /* MD_MAX72XX functions: can be found in the documentation for the library,
       * no need to customtize callback & scroll routines (unless you want to...)
      */
      uint8_t scrollDataSource(uint8_t dev, MD_MAX72XX::transformType_t t)
      // Callback function for data that is required for scrolling into the display
      {
        static char		*p = curMessage;
        static uint8_t	state = 0;
        static uint8_t	curLen, showLen;
        static uint8_t	cBuf[8];
        uint8_t colData;
      
        // finite state machine to control what we do on the callback
        switch(state)
        {
          case 0:	// Load the next character from the font table
            showLen = mx.getChar(*p++, sizeof(cBuf)/sizeof(cBuf[0]), cBuf);
            curLen = 0;
            state++;
      
            // if we reached end of message, reset the message pointer
            if (*p == '\0')
            {
              p = curMessage;			// reset the pointer to start of message
              if (newMessageAvailable)	// there is a new message waiting
              {
                strcpy(curMessage, newMessage);	// copy it in
                newMessageAvailable = false;
              }
            }
            // !! deliberately fall through to next state to start displaying
      
          case 1:	// display the next part of the character
            colData = cBuf[curLen++];
            if (curLen == showLen)				// end of character insert interchar space
            {
              showLen = CHAR_SPACING;
              curLen = 0;
              state = 2;
            }
            break;
      
          case 2:	// display inter-character spacing (blank column)
            colData = 0;
            curLen++;
            if (curLen == showLen)
              state = 0;
            break;
      
          default:
            state = 0;
        }
      
        return(colData);
      }
      
      // Callback (not used here)
      void scrollDataSink(uint8_t dev, MD_MAX72XX::transformType_t t, uint8_t col){
      // Callback function for data that is being scrolled off the display
      #if PRINT_CALLBACK
      	Serial.print("\n cb ");
      	Serial.print(dev);
      	Serial.print(' ');
      	Serial.print(t);
      	Serial.print(' ');
      	Serial.println(col);
      #endif
      }
      
      // non-blocking text display to be used in loop (call frequently)
      void scrollText(void){
      	static uint32_t	prevTime = 0;
      	if (millis()-prevTime >= scrollDelay){					// Is it time to scroll the text?
      		mx.transform(MD_MAX72XX::TSL);						// scroll along - the callback will load all the data
      		prevTime = millis();								// starting point for next time
      		}
      	}
      
      // sets the scroll delay (read from potentiometer if enabled)
      uint16_t getScrollDelay(void){
      #if USE_POT_CONTROL
      	uint16_t t = analogRead(SPEED_IN);
      	t = map(t, 0, 1023, 25, 250);
      	return(t);
      #else
      	return(SCROLL_DELAY);
      #endif
      	}
      
      void setup(){
      	// set up the display first
      	mx.begin();												// initialize display chain					
      	mx.setShiftDataInCallback(scrollDataSource);			// define function to get the scrolldata (returned as int8)
      	//mx.setShiftDataOutCallback(scrollDataSink); 			// not used
      	mx.control(MD_MAX72XX::INTENSITY, 0x01);
      #if USE_POT_CONTROL											// initialize speed potentiometer if enabled
      	pinMode(SPEED_IN, INPUT);
      #else
      	scrollDelay = SCROLL_DELAY;
      #endif
      
      	strcpy(curMessage, "I \x03 MySensors ");				// first message on display
      	newMessage[0] = '\0';									// new message initialized to empty
      	// Setup MySensors 
         //Serial in Sensor network = 115200
          gw.begin(incomingMessage, nodeId); 						// this node is 51 fixed 
          //Send the sensor node sketch version information to the gateway
          gw.sendSketchInfo("AWI Scroll MAX 51", "1.1");
       	gw.present(messageCHILD, S_INFO, "Text line Scroll");	// new S_type 20150905 (not know by domoticz)
       	gw.present(alarmChild, S_BINARY, "Alarm display");		// to display alarm text
      	gw.present(brightnessChild, S_DIMMER, "Text brightness"); // new S_type 20150905 (not know by domoticz)
          //gw.send(textMsg.set("-"));							// initialize the V_TEXT at controller for sensor to none (trick for Domoticz)
      	gw.request(messageCHILD, V_TEXT, 0); 					// request value from controller
      	// Initializations
          gw.requestTime(receiveTime);							// get the time from controller (handled by receiveTime)
      	}
      
      // loop only uses non-blocking functions
      void loop() {
      	gw.process();
      	static unsigned long lastUpdate ;						// Static hold the last update time
      	unsigned long now = millis();
      	scrollDelay = getScrollDelay();							// update scroll delay from potentiometer
      	readSerial();
          // Check for new conditions & ask for new information from controller every 10 seconds
          if (now-lastUpdate > 10000){
      		if (textAlarm){										// if alarmstatus: override all text and set max intensity
      			strcpy(curMessage, "   ALARM   ");
      			mx.control(MD_MAX72XX::INTENSITY, MAX_INTENSITY);	// set current brightness
      			mx.control(MD_MAX72XX::SHUTDOWN, false) ;
      		} else {											// standard (non Alarm actions)
      			mx.control(MD_MAX72XX::INTENSITY, textBrightness);	// set current brightness
      			mx.control(MD_MAX72XX::SHUTDOWN, textOnOff) ;
      			gw.request(messageCHILD, V_TEXT, 0); 				// request new value from controller
      		}
      		lastUpdate = now;
      	}
      	scrollText();
      }
       
      // This is called when a new time value was received
      void receiveTime(unsigned long controllerTime) {
          Serial.print("Time value received: ");
          Serial.println(controllerTime);
          setTime(controllerTime); 								// time from controller
          timeReceived = true;
      	} 
      
      // This is called when a message is received 
      void incomingMessage(const MyMessage &message) {
      	Serial.print("Message: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString());
      	if (message.sensor == messageCHILD){
      		if (message.type==V_TEXT) {						// Text content
      		strcpy(newMessage, message.getString());		// copy it in
       			newMessageAvailable = true ;
      		}
      	} else if (message.sensor == alarmChild) {
      		if (message.type==V_STATUS) {					// True/ false content
       			textAlarm = message.getBool()?true:false ;	// set alarmflag
      			Serial.print("TextAlarm: ");
      			Serial.println(textAlarm);
      		}
      	} else if (message.sensor == brightnessChild){
      		if (message.type==V_PERCENTAGE) {				// Level 0..100  content
       			textBrightness = map(message.getInt(),0, 100, 0, MAX_INTENSITY ) ;	// map to brightnesslevel 
      			Serial.print("TextBrightness: ");
      			Serial.println(textBrightness);
      		} else if (message.type==V_STATUS) {			// Display on/off
       			textOnOff = message.getBool()?false:true ;		// set shutdown/ !on/off
      			Serial.print("Text on/off: ");
      			Serial.println(textOnOff);
      		}
      	}
      }
      
      	
      // Testing purposes: input routine character buffer. Reads serial characters in buffer newMessage.
      // sets flag newMessageAvailable to true if completed
      void readSerial(void)
      {
        static uint8_t	putIndex = 0;
      
        while (Serial.available())
        {
          newMessage[putIndex] = (char)Serial.read();
          if ((newMessage[putIndex] == '\n') || (putIndex >= BUF_SIZE-3))	// end of message character or full buffer
          {
            // put in a message separator and end the string
            newMessage[putIndex++] = ' ';
            newMessage[putIndex] = '\0';
            // restart the index for next filling spree and flag we have a message waiting
            putIndex = 0;
            newMessageAvailable = true;
          }
          else
            // Just save the next char in next location
            newMessage[putIndex++];
        }
      }
      
      
      
      
      posted in My Project
      AWI
      AWI
    • RE: nRf24L01+ connection quality meter

      The sketch for the connection quality meter.

      /*
       PROJECT: MySensors / Quality of radio transmission 
       PROGRAMMER: AWI (MySensors libraries)
       DATE: 20160529/ last update: 20160530
       FILE: AWI_Send.ino
       LICENSE: Public domain
      
       Hardware: ATMega328p board w/ NRF24l01
      	and MySensors 2.0 (Development)
      	
      Special:
      	
      	
      Summary:
      	Sends a radio message with counter each  x time to determine fault ratio with receiver
      Remarks:
      	Fixed node-id & communication channel to other fixed node
      	
      Change log:
      20160530 - added moving average on fail/ miss count 
      */
      
      
      //****  MySensors *****
      // Enable debug prints to serial monitor
      #define MY_DEBUG 
      #define MY_RADIO_NRF24									// Enable and select radio type attached
      #define MY_RF24_CHANNEL 80								// radio channel, default = 76
      
      #define MY_NODE_ID 250
      #define NODE_TXT "Q 250"								// Text to add to sensor name
      
      // #define MY_RF24_CE_PIN 7								// Ceech board, 3.3v (7,8)  (pin default 9,10)
      // #define MY_RF24_CS_PIN 8
      #define DESTINATION_NODE 0								// receiving fixed node id (default 0 = gateway)
      
      #include <SPI.h>
      #include <MySensor.h>  
      
      // display
      #include <Wire.h>											// I2C
      #include <LiquidCrystal_I2C.h>								// LCD display with I2C interface
      
      
      // helpers
      #define LOCAL_DEBUG
      
      #ifdef LOCAL_DEBUG
      #define Sprint(a) (Serial.print(a))						// macro as substitute for print, enable if no print wanted
      #define Sprintln(a) (Serial.println(a))					// macro as substitute for println
      #else
      #define Sprint(a)										// enable if no print wanted -or- 
      #define Sprintln(a)										// enable if no print wanted
      #endif
      
      
      // MySensors sensor
      #define counterChild 0
      
      // send constants and variables
      int messageCounter = 0 ; 
      const int messageCounterMax = 100 ; 					// maximum message counter value 
      const unsigned counterUpdateDelay = 100 ;				// send every x ms and sleep in between
      
      // receive constants and variables
      boolean failStore[messageCounterMax] ;					// moving average stores & pointers
      int failStorePointer = 0 ;
      boolean missedStore[messageCounterMax] ;
      int missedStorePointer = 0 ;
      int newMessage = 0 ;
      int lastMessage = -1 ;
      int missedMessageCounter = 0 ; 							// total number of messages in range (messageCounterMax)
      int failMessageCounter = 0 ; 							// total number of messages in range (messageCounterMax)
      
      // Loop delays
      const unsigned long displayInterval = 1000UL ;			// display update in ms
      unsigned long lastDisplayUpdate = 0 ;					// last update for loop timers
      
      // standard messages
      MyMessage counterMsg(counterChild, V_PERCENTAGE);		// Send value
      
      // ***** LCD
      LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
      
      void setup() {
      	Wire.begin();  // I2C
          // ** LCD display **
          // LCD 2 lines * 16 char.
          lcd.begin(16, 2);
          lcd.setBacklight(HIGH);
          lcd.setCursor(0, 0);
      	lcd.print("AWI Quality nRF24");
      
      	for(int i= 0 ; i <  messageCounterMax ; i++){		// init stores for moving averages
      		failStore[i] = true ;
      		missedStore[i] = true ;
       	}
      	missedStorePointer = failStorePointer = 0 ;
          delay(1000);
      }
      
      void presentation(){
      // MySensors
      	present(counterChild, S_DIMMER, "Quality counter " NODE_TXT) ;  // counter uses percentage from dimmer value
      }
      
      
      void loop() {
      	// Sprint("count:") ; Sprintln(messageCounter) ;
      	LCD_local_display();
      	missedStore[failStorePointer] = false  ; 			// set slot to false (ack message needs to set) ; 
      	boolean succes = failStore[failStorePointer] = send(counterMsg.setDestination(DESTINATION_NODE).set(failStorePointer), true);  // send to destination with ack
      	if (!succes){
      		failMessageCounter++ ; 
      		Sprint("Fail on message: ") ; Sprint(failStorePointer) ;
      		Sprint(" # ") ; Sprintln(failMessageCounter);
      	}
      	failStorePointer++ ;
      	if(failStorePointer >= messageCounterMax){
      		failStorePointer =  0	;						// wrap counter
      	}
      	wait(counterUpdateDelay) ;							// wait for things to settle and ack's to arrive
      }
      
      void receive(const MyMessage &message) {  				// Expect few types of messages from controller
      	newMessage = message.getInt();						// get received value
      	switch (message.type){
      		case V_PERCENTAGE:
      			missedStore[newMessage] = true ;			// set corresponding flag to received.
      			if (newMessage > lastMessage){				// number of messages missed from lastMessage (kind of, faulty at wrap)
      				Sprint("Missed messages: ") ; Sprintln( newMessage - lastMessage - 1) ;
      				missedMessageCounter += newMessage - lastMessage - 1 ;
      			}
      			lastMessage = newMessage ;
      			break ;
      		default: break ;
      	}
      }
      
      
      // calculate number of false values in array 
      // takes a lot of time, but who cares...
      int getCount(boolean countArray[], int size){
      	int falseCount = 0 ;
      	for (int i = 0 ; i < size ; i++){
      		falseCount += countArray[i]?0:1 ;
      	}
      	return falseCount ;
      }
      
      void LCD_local_display(void){
      /* prints all available variables on LCD display with units
      */
      	
          char buf[17]; 											// buffer for max 16 char display
          lcd.setCursor(0, 0);
          snprintf(buf, sizeof buf, "Failed:%4d %3d%%", failMessageCounter, getCount(failStore, messageCounterMax));
          lcd.print(buf);
          lcd.setCursor(0, 1);
          snprintf(buf, sizeof buf, "Missed:%4d %3d%%", missedMessageCounter, getCount(missedStore, messageCounterMax));
      	lcd.print(buf);
      }
      
      
      posted in My Project
      AWI
      AWI

    Latest posts made by AWI

    • RE: Pan Tilt stepper motors

      @skywatch Take a look at my pan tilt project. A stepper i.s.o. servo can easily be achieved. I would recommend to use the AccelStepper lib to have a smooth movement.

      posted in General Discussion
      AWI
      AWI
    • RE: 💬 Micro (nano) ampere meter (double)

      @mfalkvidd the 'local adc' library is the hx711 library which I placed in the sketch folder. Sorry for the confusion

      posted in OpenHardware.io
      AWI
      AWI
    • RE: Double Micro (nano) Ampere meter

      @NeverDie @Nca78 a lot going on here 😀 Nice to see that my afternoon project sparked creativity.
      I started this to be a datalogger for remote monitoring of MySensors node power consumption. During the run changed my mind and it turned out to be this which fits my needs. But all options are still open..
      The converter has a max sample rate of 80Hz which was default on the board I used. I balanced accuracy and readability by applying sample averaging. This averages out much of the noise from USB source etc.
      The sparkfun boards are probably designed a little different and don't have the shield which helps to keep out noise.
      To increase speed you can change the amount of averaging (number of readings per sample)
      To get a better response for the button the way is to go for non blocking (averaging) readings of the Adc. The library is very basic so that would be the best place to start.

      posted in My Project
      AWI
      AWI
    • RE: nRf24L01+ connection quality meter

      @dakipro It would take a resistor and analog power reading to include basic power measurement. Current would vary between ~3mA and 70mA (with amplified radio).

      posted in My Project
      AWI
      AWI
    • RE: Your workshop :)

      @core_c Thanks, I missed that 😉

      posted in General Discussion
      AWI
      AWI
    • RE: Your workshop :)

      @gohan I used a kit. There is also a description and suggestions on improvement of the "Chinese clones" in the documentation of the project.

      posted in General Discussion
      AWI
      AWI
    • RE: Your workshop :)

      @Yveaux I soldered the thing myself so build quality is .... 😉 The board I received looks to be solid as well as the components.
      Accuracy in resistor/ capacitor meaurement is fine (~5% which is also the toleration of the components tested) Semiconductor analysis is enough for me with Fet / Junction transistors as I can determine the most important characteristics (including the pin layout!) which are within 10% of the datasheet. (pins are 100% correct :-))

      posted in General Discussion
      AWI
      AWI
    • RE: Your workshop :)

      @gohan said in Your workshop 🙂:

      Aren't these devices basically Arduinos? It's written on the title atmega328. If so if we could get our hands on the code, we could make our own 😀

      I finally found the place where the Chinese get their code and design for the "Transistortester". It comes from a german site
      0_1494697102560_upload-93c9329f-c8ba-4dd1-bf66-1757acf21a03 a very extensive project. I doubt if I will ever be able to match or even comprehend what they accomplished. 🙇

      posted in General Discussion
      AWI
      AWI
    • RE: DC meter for PV ouput measuring and data logging

      @tailchopper I wonder if you wouldn't be better of on another forum. MySensors provides an infrastructure for home-automation and IoT. If you are not into connecting it to a MySensors ecosystem there are some dedicated PV (power monitoring) forums which probably give you more focussed / better answers. Like Openenergymonitor

      posted in Hardware
      AWI
      AWI
    • RE: DC meter for PV ouput measuring and data logging

      @tailchopper It would depend on the output voltage & current of your PV panel. Up to 26V 3.2A the ina219 is a very convenient all-in-one sensor with I2C interface.
      0_1494335149650_upload-92a172d0-6957-42b4-8c63-acf755f18498

      posted in Hardware
      AWI
      AWI