E3D toolchanger Z-homing met Voron TAP mogelijk?

HOE WERKT HET NU BIJ DE E3D TOOLCHANGER

Het systeem waarbij de E3D toolchanger de Z-waarde van de 4 tools bepaalt ligt vast in de vooringestelde systeemfiles.  Dat betekent dat je per tool een Z-homing papertest doet om te bepalen wat de afwijking per tool is ten opzichte van T0, dat is de meest linker tool.  Het resultaat zet je in de config file als Z-waarde per tool\ waarbij ik voor T0 meestal ‘0’ gebruik en de Z-probe algemene waarde gebruik, die ik bepaal als verschil tussen manuele probe op het wagentje versus de nozzle hoogte van T0.

Eerst moet je dan dus bepalen wat de Z-afwijking is van T0 ten opzichte van de Z-waarde van het wagentje dat de tools oppikt. Dat gebeurt door dat kale wagentje met een Z-probe schakelaartje onder het wagentje de Z-waarde=0 op het bed te laten homen.

Daarna doe je een tool pickup van T0 en meet je wat de hoogte van T0 is als Z waarde. Die waarde vul je dus in bij de probe waarde in je config file. Dat vind ik allemaal best omslachtig, ook al omdat alles steeds verandert wanneer je bijvoorbeeld een keer een nozzle verwisselt.

GEWENSTE SITUATIE

Het liefst zou ik elk van de 4 Tools, dus T0 t/m T3 gewoon elke printbeurt X,Y en Z laten homen, en dan kan je er ook gelijk één uitkiezen om de bed mesh te doen.

Die 4 Z-waardes neem je vervolgens als Z=0 waarde per Tool en klaar. Dat werkt bij de Voron die ik met TAP Z-homing heb draaien geweldig! Wat je ook doet met je bed of met je hotend, gantry enzovoorts. Het maakt niet uit want de nozzle wordt als mechanische Z- homing tip gebruikt.

 

De tool pickup (het karretje) zit wel erg stabiel vast aan de X-as. Het mooiste zou zijn om dit geheel te laten bewegen in de hoogte om de TAP functie mogelijk te maken. Dat is nog een uitdaging, ook omdat de a-en b riemen aan dit karretje zijn bevestigd.  Dit lijkt alleen mogelijk met een nieuw karretje waar de riemen aan zitten en een losse toolchanger pickup er naast of er voor. Tussen beide delen moet ik dan nog de TAP functie maken.. En- als de toolchanger er voor komt moet de X- as even ver naar achter op de Y-assen worden geplaatst.  Weet niet hoe dat moet gaan passen…

Na het verkennen van allerlei mogelijkheden is deze overgebleven: De tool pickup op dezelfde plaats houden en met bestaande middelen werken. Het  montageblok op de X-as slider in 3 delen zagen en daarna het middenstuk  aan beide montagekanten 1 mm affrezen. De zijplaten waar de riemen aan zijn gemonteerd aanpassen zodat deze platen weer aan het middendeel van het sliderblok kunnen worden gemonteerd met nieuwe verzonken schroeven.  De doorgaande bussen aan de onderkant gaan niet meer door de plaat heen en de plaat moet net zoals aan de bovenkant op de hoeken worden weggefreesd. zodat ca. 5 mm verticale speelruimte ontstaat.  De 2 onderste verbindingspunten van beide zijdelen elk met 2 x 1 mm opvulringen monteren zodat het karretje op en neer kan bewegen en de zijkanten op de originele afstand van elkaar blijven in verband met de stevigheid van de bewegende constructie. Op het middendeel montageblok van de X-as slider komt een extra montageblok voor de verticale lineair rail van de TAP-slider. Op de voor en/of achterkant van de tool pickup komen verlengstukken waarop de TAP-slider met het bewegende deel wordt vastgemaakt zodat alles ca 3-4mm op en neer kan.

De manier waarop bij een Voron2.4 3d printer de TAP functie werkt

EXTRA WENS: Zelfzoekende toolchanger

En als ik toch bezig ben: Gelijk maar een zelfzoekende toolchanger maken?  Grof instellen met de XYZ coördinaten per tool, het laatste stuk elektronisch met een geleidesysteem tussen het pick-up wagentje en de tool en de finale passing met de bestaaande mechanische passing.

In plaats van precies te bepalen met passen en meten waar elke tool moet worden opgepikt en weggezet zou je via een elektronisch gidssysteem precies kunnen richten -en- wanneer er gewisseld moet worden van tool- gelijk uitkomen bij de juiste tool.  Geen X-Y instellingen gedoe met assen homen meer.  Want als er ook maar iets verandert als gevolg van mechanische stress in het frame of door kleine afwijkingen van de X en Y homing, gaat het oppikken en wegbrengen van tools regelmatig fout.

Een mogelijke manier om dit te doen kan een passage LED/LASER systeem zijn, zoals gebruikt bij entrees van winkels.

 

 

mini focusseerbare laser module

 

mini laser receiver module

 

Of gewoon infrarood gebruiken, dat zie je niet maar is ook veel minder gevaarlijk

 

Hierbij gebruik je een richtlaser zoals in een levelling systeem of een infrarode laser met -ontvanger .

Deze komt dan boven op de X-as aan de bewegende toolhead en is gericht naar de tools, 90 graden ten opzichte van de X-as.

Vervolgens activeer je als ontvanger de juiste tool waar je naar toe wilt voor het wegbrengen of oppikken.

Met een X-sweep beweging kun je contact zoeken met de ontvangende tool en daarna in 1 rechte lijn naar de tool bewegen tot aan het pick-up punt dat in absolute Y-waarde vastligt in de config file.   Lijkt me mooi om te ontwikkelen!

EXTRA WENS: Nauwkeurige XYZ homing van de tools

En ik zou graag een manier hebben om X, Y en Z van elke tool nozzle in detail ten opzichte van de andere tool nozzles te centreren, net zoals bij mijn CNC machines:

3D Print Head Alignment Block

Met zo’n head alignment block kun je bij een CNC machine van alle assen een nauwkeurige positiebepaling doen.  Vooraf moet je wel vaststellen waar dit block ongeveer staat, binnen een nauwkeurigheid op X en Y van ca. 1 mm.

Dat alignment block is elektrisch geïsoleerd opgesteld en deze opzet werkt op basis van contact maken tussen de gebruikte tool tip en het block.

Hoe werkt het homen met een alignment block

  • Je programmeert in gcode een centreermacro.
  • Eerst zet je tijdelijk de motorvermogens op een zo laag mogelijke waarde, om niets te beschadigen wanneer er iets in de weg staat van de af te leggen moves.
  • Net zoals wanneer ik regulier een home-all doe, zet je ook bij deze nieuwe methode het bed en de betreffende tool-nozzle in de gebruiks modus (bijvoorbeeld bed op 70 graden en nozzle op 180 graden).
  • Vervolgens doe je een normale XY homing, die in mijn geval met eindschakelaars (of optische schakelaars) aan het begin van de X en Y assen werkt.
  • En een Z-homing actie is ook nodig tenzij je de Z-moves blokkering die optreedt wanneer je Z niet eerst hebt gehomed niet wilt opheffen.
  • Daarna ga je met de Z-as voldoende omhoog om het block niet te raken.
  • Vervolgens ga je naar de absolute XY positie van het block.
  • Wanneer je boven het block bent met je tool home je Z.
  • Daarna home je op Z+0.3 zowel -X als +X, en in het midden van -X en +X home je -Y en +Y.
  • Het resultaat daarvan is de exacte positie van het center op het platte Z-vlak van het alignment block.
  • Omdat je exact weet wat de positie hiervan is ten opzichte van het bed-center en vanaf X0, Y0 en Z0 kun je dit gelijk in de macro vertalen en de Z0, X0 en Y0 waarden meegeven als absolute waarden.

Het zou mogelijk moeten zijn om de tools van de E3D toolchanger ook op deze manier te homen, waarbij Z met de TAP functie kan en X en Y de elektrische detectie kunnen gebruiken zoals hierboven voor de CNC freesmachines is beschreven.  We zullen zien of en hoe dit gaat werken als aanvulling op de TAP-Z homing met de huidige X- en Y- microschakelaars homing op de X en Y assen

 

NAWOORD

Het credo lijkt nu nog te zijn: Als de E3D toolchanger het doet, moet je er verder vooral van afblijven.  Dat komt mij helemaal niet zo uit omdat ik mijn printers nogal eens van plek verwissel. En dat blijkt niet altijd goed te gaan.

Dus die zaken ga ik uitzoeken en als het kan, ook bouwen!

Geeetech A30M 3d printer

UPDATE MET NIEUW Duet2wifi MOTHERBOARD

Midden juni 2020 ben ik gestart met de Geeetech A30M desktop 3d printer.
De printer kan 2 kleuren gemixed printen met 2 filament geared drive units bovenop het frame en een fan voor elke aanvoer naar het gecombineerde hotend.

Op deze printer zijn een paar aanpassingen nodig, als je er echt goed mee wilt werken.
Allereerst heb ik veel last gehad van de standaard herrie van de 24 Volts fan onder de bodemplaat, die moet zorgen voor koeling van het motherboard. Deze fan draait altijd op vol vermogen.
Ik heb er een regelaar tussen geplaatst met bediening aan de linker zijkant, via een geboord gat. de regelaar heb ik met 2 tie-wraps vastgezet door de koelsleuven aan de linker zijkant. Het draaiknopje komt net door de kast heen en je ziet er nauwelijks iets van. De meeste motherboards die ik gebruik hebben geen fan nodig voor de koeling omdat ze vrij in het open frame zijn geplaatst maar de A30M heeft een gesloten behuizing waardoor een beetje luchtcirculatie wel nodig is. Plan is om een thermostaatregeling toe te voegen zodat het knopje niet meer nodig is. Later. De regelaar staat op de stand dat er wel veel luchtverplaatsing is maar zonder het gieren van de fan.

Tweede aanpassing is de toevoeging van een Geeetech 3d touch op het hotend. De beugel was meegeleverd bij de printer, geschikt voor zowel een dikke inductieve sensor als voor de 3d touch sensor. Fijn is dat de software (of firmware, zo je wilt) als geschikt is vanaf fabriek voor autoleveling. Let wel op de juiste plaatsing van de connectors, vanaf de voorzijde gezien moeten de bruine en zwarte draden naar rechts worden gemonteerd.

Nadeel is dat de firmware af-fabriek niet echt lekker werkt met auto leveling. In het midden van het hotbed gaat alles prima maar bij grotere prints merkte ik dat de eerste laag erg verschillend werd geprint, waardoor alles steeds loskwam. Nu werk ik dus met handmatige leveling terwijl er automatische leveling mogelijk is..

Het hotbed is lekker groot met een werkbare omvang van 320x320mm. De printhoogte is 420mm.

De prijs was ruim 400 Euro, en de levering was vanuit Duitsland.

Ik raad iedereen aan om ALLES vast te zetten en vooral de blokhaak erbij te pakken. Mijn exemplaar was echt niet goed gemonteerd. Alle draden waren OK maar alle bouten zaten of te vast dan wel niet vast. Daar kwam ik pas achter bij de eerste proefprint. Gelijk gestopt en alles nagelopen. Let vooral op de rolwielen van het hotbed. Daar kun je moeilijk bij maar in mijn geval waren de stelwielen helemaal niet gesteld en ze draaiden dus niet mee. Nadeel van zo’n desktopprinter is dat je nauwelijks plek hebt onder het hotbed.
De verticale V-profielen waren niet haaks gemonteerd op het bovenste profiel. Dat is lastig te herstellen omdat alles doorgeboord is en met bouten is vastgezet. Ik adviseer om aan de achterkant in de bovenste 2 hoeken hoekverstevigers te plaatsen. Ik heb ze in bestelling en daarna kunnen ze er gelijk op.

En.. wat sommige grote printers wel hebben en de A30M niet: Extra stabilisatiestangen naar de voorkant (of naar achter, dat kan ook) zodat de verticale profielen niet kunnen bewegen. Nu zit er wanneer je een beetje kracht uitoefent ca. 2mm speling op, ondanks de stevige bevestiging aan de desktop behuizing.

2GSpro Delta

Mijn Deltaprinter, een Geeetech Rostock 2GSpro met 2 extruders heeft eigenlijk nooit echt goed gewerkt. De op Arduino mega gebaseerde moederprint is langzaam en als gevolg van de calculaties die het board steeds uitvoert door het vertalen van de G-codes naar besturing van de ABC motoren, lijt het allemaal net niet te lukken.

Prints zijn rafelig en aan de hardware lijkt het niet te liggen.

Voor deze printer heb ik een Duet wifi V1.04 motherboard besteld, dezelfde die ik voor de Prusa Bear installeer. Met een 4.3.inch touchscreen erbij. Zie de bouw van deze upgrade HIER:

Het installeren zal weinig problemen opleveren, de print gaat onder de printer net zoals het bestaande GT2560 board en ik schakel dan gelijk over van Arduino (en Marlin) naar reprap software.  Kwestie van smaak, maar Marlin en Arduino is erg traag bij elke update terwijl ik met bijvoorbeeld Smoothieware en een lokale config file veel snellere  veranderingen en dus ook uploads kan doen.

 

Prusa Bear

Juni 2020 ben ik, op basis van alle ervaringen met de 3d printers en laser cutters, een eigen ontwerp gaan maken voor een klein model 3d-printer.  uiteindelijk heb ik gekozen voor de Prusa Bear uitvoering, waarin ik alle verbeteringen gelijk meeneem.

Dus wel de 8mm rods voor X, Y en Z bewegingen maar ook het rigid frame met 2040 extrusie aluminium profiel.

Een 24 Volts voeding, hotbed en extruder en een Duet wifi motherboard met touchscreen bediening.

En ik maak m gelijk lekker stil. Geen jankende fans en geen jankende stappenmotoren.

Eerst het frame aangeschaft, daarna alle printable delen in PetG geprint op de Ender 3:

Boven:  Frame in elkaar gezet en de eerste delen gemonteerd (1-7-2020)

Onder: Alles gemonteerd (midden juli 2020), glasbed erop en eerste testprints gemaakt. Ben nog niet tevreden over de (on)gelijkloop van beide Z motors.  De Duett kan ze apart aansturen en dan moet ik eerst nog even 2 endstops maken op de Z assen, en strak gelijk maken.  Het worden optical stops vanwege de goede repeatability.  Dan kan ik homen en aslevelen op de endstops en bedlevelen met de BLtouch probe.  Weet even niet hoe dat in het NL heet, -).

 

Zelfbouw 3d CoreXY printer

Mijn wens is om naast de bestaande printers een 3Dprinter te maken met een extra groot werkoppervlak.  Daarmee wil ik onder andere een paar gootstukken en onderdelen voor de blower van de airco in een oude auto printen.

Ondertussen heb ik heel wat verschillende 3d-printers (na-) gebouwd, hier en daar met delen van andere printers of met aanpassingen naar eigen inzicht en ervaring.

De beschrijvingen daarvan zijn in het Engels gemaakt en kun je HIER op mijn website vinden.

Mijn ervaringen met CoreXY printers zijn uitstekend vanwege de grote nauwkeurigheid en hoge printsnelheid,  zodat ik dit type heb gekozen voor mijn gewenste printformaat van 500x500x500 mm.

Het wordt een stille printer met 3 extruders voor 3 soorten/kleuren filament (gelijktijdig of apart) en 1 nozzle.

Alle benodigde materialen zijn op voorraad, en het belangrijkste is de keuze voor de definitieve opzet van de printer.

Omdat ik een zo klein mogelijke printer wil hebben ondanks de grote printmaat zijn de keuzes qua bouw behoorlijk beperkt.  De volgende uitgangspunten zijn leidend bij de bouw:

  • Te gebruiken extrusie-materiaal is aluminium type 2040 van max 60cm lang, deze heb ik voldoende op voorraad;
  • Kast moet eenvoudig gesloten kunnen worden gemaakt, dus niet teveel delen die buiten de extrusie steken;
  • De X-Y Gantry is vast gemonteerd bovenin de printer en beweegt niet op de Z-as;
  • Voor de Y-as worden 2 lineaire rails MGN9H van 60cm lang gebruikt;
  • Voor de X-as wordt 1 lineaire rail MGN12H van 60 cm lang gebruikt;
  • Het bed is bewegend op de Z-as en gelagerd met LUU 8 mm bussen op  4 stuks  ‘rods’van 8mm;
  • De X- en Y motoren zijn buiten de framehoeken geplaatst voor maximale X- en Y uitslag (breedte en lengte van de beweging van het hotend);
  • Er is 1 Z-motor die via één closed loop belt beide schroefassen aandrijft voor de Z-beweging van het bed;
  • Er komt een triple hotend in, luchtgekoeld met 3 bowden extruders en 1 gezamenlijke nozzle;
  • Voor het besturingsdeel heb ik een  bestaand Duet wifi board gekozen. Daar moet nog wel een DUEX uitbreidingsboard bijkomen voor de extra extruders.

 

Voorbeeld voor de onderkant en Z-as aandrijving (van een Ender3-ombouw naar CoreXY):

Voorbeeld motorplaatsing bij een H-BOT gantry:

en bij een CoreXY met rods ipv linear rails:

En nog een voobeeld met linear rails maar dan aan de binnenkant van de Y-legs.

Mijn ontwerp:  Ik wil de Y-rails bovenop plaatsen zodat er meer schuifruimte komt voor de X-as en het hotend in zijwaartse richting.  De X-as komt aan de zijkant zodat er maximale ruimte komt tussen beide Y-extrusies.  Theoretisch krijg je dan een kastbreedte van 500 mm (gewenste bruikbare bedbreedte) plus 5cm (de breedte van het hotend) plus 4 cm (2 maal extrusiebreedte), samen 590 mm, afgerond 60 cm.  Omdat ik openbuild corners van 2x2cm gebruik is de breedte gelijk aan de diepte bij gebruik van 60cm extrusie 60+ (2x2cm)=64 cm.   De hoogte is dan 60cm+ (2×4) =68cm.

Ontwerp gantry:

Ronde klok WS2812 & Arduino nano

ABOVE: Circular clock, completed project, reading 05h:41m and crossing to 05h:42m.  Red=hours, Green=minutes

Above: Clock without case, with open components.

READ THIS ARTICLE IN ENGLISH

In de bovenstaande video zie je alle benodigde onderdelen voor de electronica.  Een arduino Nano, een tijdmodule LS3231 met batterij back-up en een 4-delige ring met elk 15 stuks WS2812 LED’s die zorgen voor een 160mm 60 LED units klok.  Je kunt hem bouwen als een open gebouwde unit zoals hierboven afgebeeld met draad of in een 3d printbare slanke behuizing die ik heb ontwikkeld.  Zie de foto’s hieronder.

Voor het bouwen van deze mooie nauwkeurige klok, kun je mijn ontwerp files voor de behuizing gebruiken op elke 3d printer met een horizontale bed maat van minimaal 165x165mm.

Download de beide print STL’s OF van de Prusa gedeelde site waar ik deze ontwerpen heb geupload (zoek op de prusa site naar ws2812 circulaire arduino klok).

OF haal het STL bestand voor de VOORKANT van de klok van mijn website HIER

EN haal het STL bestand voor de ACHTERKANT van de klok van mijn website HIER

Eén STL is voor de achterkant en bevat de Nano box, de andere is voor de voorkant van de klok.  Positioneer de achterste STL 180 graden (dus omhoog gaat omlaag) in uw slicer, zodat zowel de doos als de LED-behuizing op Z-0 niveau zijn, d.w.z. naar beneden gericht op hetzelfde horizontale niveau.   De voorkant kan het best geprint worden met de platte kant naar beneden.  ABS is niet aan te raden omdat het minder stijf is, maar zal waarschijnlijk ook werken.  Voor mij werkt PETG of PLA het beste.

Gebruik wit filament voor het voorste deel, de achterkant kan elke kleur zijn die je wilt.

In de cirkel worden de 4 WS2812 LED segmenten in 1 volledige cirkel van ongeveer 160mm geplaatst.

Als je de elektronica aan de achterkant hebt aangesloten, schuift de voorkant er zo overheen. Geen lijm nodig.  Maar de LED ring kan best op 4 plaatsen met een druppel hotglue aan de basis van de achterste behuizing gelijmd worden.  Dit kun je het beste doen als je zeker weet dat alles goed werkt.

De LED onderdelen zijn verkrijgbaar op o.a. banggood , aliexpress en zo, zoek naar 60LED circle WS2812 die de 160 mm buitendiameter heeft.

Elke LED vertegenwoordigt een punt voor seconden, minuten of als uur indicator.

De kleuren bepalen de functie.  Blauw wordt ook gebruikt als kwartier indicator met minder intensiteit, om een gevoel van positionering te hebben voor de andere LEDS als het donker is.

Kijk naar de video hierboven van het ‘open’ demonstratiemodel om te begrijpen hoe het werkt.

Hieronder vindt je de Arduino code voor de gebruikte Nano3, as-is. het werkt voor mij, en in de code vindt u ook alle benodigde elektrische aansluitingen en de specificaties van de gebruikte Time module.

Haal de Arduino code HIER

Wanneer aangesloten op je PC, kun je de Arduino programmeren en via de seriële interface kun je naderhand speciale instellingen van de klok wijzigen, zoals helderheid, speciale kwartierverlichtingsindicatoren, enzovoort. het staat allemaal in de code hieronder.

De aansturing kan via een seriële interface met de usb ingang van de Arduino, via een terminalprogramma zoals YAT of met de interface van het Arduino IDE programma.

De commando’s zijn:

f; fader UIT
F; fader AAN
m (getal); dim de 4 blauwe marker LED’s met waarde (getal)
S; synchroniseren met RTC tijd
s; synchroniseren met systeemtijd (computer)
t (tijd); systeemtijd veranderen in:
b; helderheid van alle niet-marker LED’s

Doneer a.j.b. $1 aan mijn paypal account als je (delen van) mijn ontwikkelde materialen gebruikt, zodat ik kan doorgaan met het delen van leuke dingen voor jou om te downloaden

Ik hoop dat alles goed gaat lukken!

Succes,

Jan

De Arduino code, te gebruiken voor het programmeren van de Arduino Nano3 is beschikbaar onderaan dit bericht als platte tekst om te importeren in een leeg arduino bestand (met kopiëren en plakken).

Zorg ervoor dat je alleen de bibliotheken en tijdmodule gebruikt die in de code zijn aangegeven!  De gebruikte tijdmodule is van de betere generatie die de tijd zeer goed vasthoudt, ook in stand-by.

Gebruik voor het verbinden van de draden tussen de neopixel segmenten, de arduino en de tijdmodule een temperatuurgeregelde soldeerbout.  Gebruik een ventilator als je aan het solderen bent en adem geen giftige gassen in tijdens het solderen.

De Arduino code is hieronder weergegeven, te importeren in Arduino IDE in een .ino bestand.  Met de Arduino IDE moet je vervolgens de code compileren om de Arduino Nano geflasht te krijgen met het programma.


/**
* NeoClock
*
* Clock using 60 WS2812B/Neopixel LEDs and DS3231 RTC
* Small changes and updates made by jan Griffioen, Amsterdam Europe 2018-2021
* Libraries needed:
* * Adafruit NeoPixel (Library Manager) – Phil Burgess / Paint Your Dragon for Adafruit Industries – LGPL3
* *
* * Arduino Timezone Library (https://github.com/JChristensen/Timezone) – Jack Christensen – CC-BY-SA
* * Time Library (https://github.com/PaulStoffregen/Time) – Paul Stoffregen, Michael Margolis – LGPL2.1
*/

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

#if defined(ESP8266)
#include <pgmspace.h>
#else
#include <avr/pgmspace.h>
#endif

/* for software wire use below
#include <SoftwareWire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>

SoftwareWire myWire(SDA, SCL);
RtcDS3231<SoftwareWire> Rtc(myWire);
for software wire use above */

/* for normal hardware wire use below */
#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>
RtcDS3231<TwoWire> Rtc(Wire);
/* for normal hardware wire use above */

#include <TimeLib.h> //http://www.arduino.cc/playground/Code/Time
#include <Timezone.h> //https://github.com/JChristensen/Timezone

#include <EEPROM.h>

//Central European Time (Frankfurt, Paris)
TimeChangeRule CEST = {“CEST”, Last, Sun, Mar, 2, 120}; //Central European Summer Time
TimeChangeRule CET = {“CET “, Last, Sun, Oct, 3, 60}; //Central European Standard Time
Timezone CE(CEST, CET);

TimeChangeRule *tcr; //pointer to the time change rule, use to get the TZ abbrev
time_t utc;

#define PIN 5

unsigned long lastMillis = millis();
byte dimmer = 0x88;
byte hmark = 0;

byte ohour=0;
byte ominute=0;
byte osecond=0;

boolean fader=true;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

void setup() {

Serial.begin(57600);

strip.begin();
strip.setBrightness(50);

// Some example procedures showing how to display to the pixels:
// colorWipe(strip.Color(255, 0, 0), 50); // Red
//colorWipe(strip.Color(0, 255, 0), 50); // Green
//colorWipe(strip.Color(0, 0, 255), 50); // Blue
//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
// Send a theater pixel chase in…
//theaterChase(strip.Color(127, 127, 127), 50); // White
theaterChase(strip.Color(127, 0, 0), 50); // Red
//theaterChase(strip.Color(0, 0, 127), 50); // Blue

//rainbow(20);
rainbowCycle(2);
//theaterChaseRainbow(50);

strip.clear();
strip.show(); // Initialize all pixels to ‘off’

Rtc.Begin();

Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);

if (!Rtc.GetIsRunning())
{
Serial.println(“Rtc was not actively running, starting now”);
Rtc.SetIsRunning(true);
}

if (!Rtc.IsDateTimeValid())
{
// Common Cuases:
// 1) the battery on the device is low or even missing and the power line was disconnected
Serial.println(“Rtc lost confidence in the DateTime!”);
}

byte eechk = EEPROM.read(0);
if(eechk == 0xAA) { //Assume this is our config and not a fresh chip
dimmer = EEPROM.read(1);
hmark = EEPROM.read(2);
fader = EEPROM.read(3);
}

timeSync();
}

void calcTime(void) {
utc = now();
CE.toLocal(utc, &tcr);
ohour = hour(utc);
ominute = minute(utc);
if(osecond != second(utc)) {
osecond = second(utc);
lastMillis = millis();

if(ominute == 0 && osecond == 0) {
//Every hour
timeSync();
}
}
}

void addPixelColor(byte pixel, byte color, byte brightness) {
color *= 8;
uint32_t acolor = brightness;
acolor <<= color;
uint32_t ocolor = strip.getPixelColor(pixel);
ocolor |= acolor;
strip.setPixelColor(pixel, ocolor);
}

void drawClock(byte h, byte m, byte s) {
strip.clear();

addPixelColor(m, 1, dimmer);

if(hmark > 0) {
for(byte i = 0; i<12; i++) {
addPixelColor((5*i), 2, hmark);
}
}

h %= 12;
h *= 5;
h += (m/12);
addPixelColor(h, 2, dimmer);
// 0x RR GG BB

if(fader) {
byte dim_s1 = dimmer;
byte dim_s2 = 0;
byte px_s2 = s+1;
if(px_s2 >= 60) px_s2 = 0;
unsigned long curMillis = millis()-lastMillis;
if(curMillis < 250) {
dim_s2 = 0;
dim_s1 = dimmer;
}else{
dim_s2 = map(curMillis, 250, 1000, 0, dimmer);
dim_s1 = dimmer – map(curMillis, 250, 1000, 0, dimmer);
}

// Add blue low intensity dots for 12(0),3, 6 and 9 O’çlock to verify where the clock is positioned..
addPixelColor(15, 128, 10);
addPixelColor(30, 128, 10);
addPixelColor(45, 128, 10);
addPixelColor(0, 128, 40);

addPixelColor(s, 0, dim_s1);
addPixelColor(px_s2, 0, dim_s2);
}else{
addPixelColor(s, 0, dimmer);
}

// add a background color
// setBrightness(Serial.parseInt());
// uint16_t j;
// for(j=0; j<60; j++) { // 1 cycles of colors on wheel
// strip.setPixelColor(j, Wheel(((j * 256 / strip.numPixels()) + j) & 255));
// }

strip.show();
}

byte rounds = 0;

void loop() {
calcTime();

if(rounds++ > 100) {
Serial.print(ohour);
Serial.print(“:”);
Serial.print(ominute);
Serial.print(“:”);
Serial.print(osecond);
Serial.println(“(C)JG-2020”);
rounds = 0;

}
//rainbow(21);
if (osecond == 59){theaterChase(strip.Color(0, 0, 127), 40); }// Blue; }
//if (ominute == 59 AND osecond == 59){theaterChase(strip.Color(0, 127, 0), 50); }// Green}
//if (ohour == 11 AND ominute == 59 AND osecond == 59){theaterChase(strip.Color(127, 127, 0), 50); }// Green}
else {drawClock(ohour,ominute,osecond);}

delay(10);

chkSer();
}

void timeSync(void) {
RtcDateTime dt = Rtc.GetDateTime();
setTime(dt.Hour(),dt.Minute(),dt.Second(),dt.Day(),dt.Month(),dt.Year());

Serial.print(“Synced to: “);
Serial.print(dt.Year());
Serial.print(“-“);
Serial.print(dt.Month());
Serial.print(“-“);
Serial.print(dt.Day());
Serial.print(“-“);
Serial.print(dt.Hour());
Serial.print(“-“);
Serial.print(dt.Minute());
Serial.print(“-“);
Serial.println(dt.Second());
}

void timeSave(void) {
utc = now();

RtcDateTime store = RtcDateTime(year(utc), month(utc), day(utc), hour(utc), minute(utc), second(utc));
Rtc.SetDateTime(store);

Serial.print(“Synced to: “);
Serial.print(year(utc));
Serial.print(“-“);
Serial.print(month(utc));
Serial.print(“-“);
Serial.print(day(utc));
Serial.print(“-“);
Serial.print(hour(utc));
Serial.print(“-“);
Serial.print(minute(utc));
Serial.print(“-“);
Serial.println(second(utc));

}

void setBrightness(byte brightness) {
dimmer = brightness;
}

void chkSer(void) {
unsigned int iy;
byte im,id,iH,iM,iS;

if(!Serial.available()) return;

switch(Serial.read()) {
case ‘b’:
setBrightness(Serial.parseInt());
Serial.print(F(“Brightness changed to: “));
Serial.println(dimmer);
EEPROM.put(0, 0xAA);
EEPROM.put(1, dimmer);
break;
case ’t’:
iy = Serial.parseInt();
im = Serial.parseInt();
id = Serial.parseInt();
iH = Serial.parseInt();
iM = Serial.parseInt();
iS = Serial.parseInt();
setTime(iH,iM,iS,id,im,iy);
Serial.println(F(“System time changed”));
break;
case ‘f’:
fader = false;
EEPROM.put(0, 0xAA);
EEPROM.put(3, 0);
Serial.println(F(“Fader off”));
break;
case ‘F’:
fader = true;
EEPROM.put(0, 0xAA);
EEPROM.put(3, 1);
Serial.println(F(“Fader on”));
break;
case ‘m’:
hmark = Serial.parseInt();
EEPROM.put(0, 0xAA);
EEPROM.put(2, hmark);
Serial.println(F(“HMark changed”));
break;
case ‘s’:
timeSync();
Serial.println(F(“Synced RTC to System”));
break;
case ‘S’:
timeSave();
Serial.println(F(“Synced System to RTC”));
break;
default:
Serial.println(‘?’);
}
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}

void rainbow(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 25));//255
}
strip.show();
delay(wait);
}
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<4; j++) { //do 4 cycles of chasing
for (int q=0; q < 3; q++) {
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();

delay(wait);

for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();

delay(wait);

for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r – g – b – back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 – WheelPos;
if(WheelPos < 85) {
return strip.Color(255 – WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 – WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 – WheelPos * 3, 0);
}

error: Content is protected !!