You are on page 1of 46
BANDA TRANSPORTADORA DESARMABLE ‘O Y CONTROL DE VELOCIDAD CON ARDU BANDA TRANSPORTADORA MODULAR Y DESARMABLE Este proyecto surge como necesidad de tener una replica en miniatura de un sistema industrial en este caso una banda transportadora para ser usada con fines educativos para el entrenamiento en automatizacion industrial ya sea mediante PLC, Arduino, Raspberry Pi o alguna otra plataforma programable mediante software. En general existen 2 eategorias para estos dispositivos: Los que ya vienen listos para usar y que por lo generalmente son bastante robustos y muy bonitos esteticamente hablando y los que se pueden fabricar en casa con materiales relativamente economicos y faciles de conseguir, La gran mayoria de estos equipos listos para usar son costosos para muchas escuelas e instituciones, ademas sus piezas de repuestos solo pueden conseguirse por medio del fabricante oficial Por otto lado la gran mayoria de bandas transportadoras que se encuentran publicadas en internet, son construidas en madera y plastico ( la gran mayoria de veces usando elementos muy economicos o reciclados ). Si bien estos disefios son validos como pruebas de cancepto o como proyectos de fin de curso, no son lo suficientemente robustos para poder ser usado por alumnos por muchos dias consecutivos sin que se daften El disefio aqui presentado trata de reunir lo mejor de ambos mundos con las siguientes caracteristicas: + Apariencia industrial + Se puede desarmar y armar multiples veces sin generar dailo alguno, Mas informacion: ‘Automatizanos.com @automatizanos + Puede ser almacenado muy poco espacio, facilitando el transporte cuando no se usa. + Piezas de repuesto se pueden conseguir con relativa facilidad ESTRUCTURA BASICA USANDO COMPONENTES INDUSTRIALES Para la coustruccion de la estructura basica se sugiere que se use el mostrado en "estructura ‘miversal para planta piloto" publicado en un articulo anterior. Una de las grandes diferencias es que en este proyecto se deben introducir previamente al al perfil las 12 tuercas en T que fijaran los rodamientos, las 2 tuercas en T que fijaran el soporte del motor y otras dos adicionales que fijaran la electronica de control. Esto debe hacerse antes de armar el marco. A continuacion se presentara una lista de referencia de los componentes a utilizarse, puesto que depende de cada persona las dimensiones finales del montaje ( que dependeran de las longitudes de los perfiles elegidos) asi como Ia cantidad de ejes que se ubicaran a lo largo de la banda. * Perfil de aluminio extruido 2020 ranurado en T "largos" * Perfil de aluminio extruido 2020 ranurado en T "cortos" + Angulo interno en forma de L y tomillos prisioneros con cabeza allen + Cojinete de sujecién con rodamiento intemo para varilla de 8mm + Tomillos cabeza hexagonal allen M3 x 8 ‘Tuerea para ramura en T Ejes lisos en acero de mm Banda dentada GT2 Motor paso a paso NEMA 17 + Soporte en angulo para motor paso a paso NEMA 17 + tomillos cabeza hexagonal allen M3 x 6 * Polea dentada 16 dientes GT? para motor Smm Mas informacion: ‘Automatizanos.com @antomatizanos + Polea dentada 20 dientes GT2 para ejes 8mm + Llaves hexagonales allen de 1.5.2 y 4 mm TRANSMISION DE MOVIMIE! \TO Este diseto esta concebido para que tener la menor cantidad posible de elementos mecanicos, sin embargo se requiere la realizacion de dos pasos muy especificos que no son tan triviales: Cortar y pegar la correa dentada que transmite el movimiento del motor a uno de los ejes. y confeccionar la banda o cinta transportadora propiamente Banda dentada a la medida Sino de dispone de una banda dentada del tamafo respectivo, se puede confeccionar una a la medida usando una banda mas grande, cortandola y pegandola de algun modo. La forma mas simple de hacer esto sin utilizar elementos especializados para este proposito, consiste en lijar 0 remover un poco los dientes de un lado de la banda, pegar los dos extremos mediante un pegamento para caucho (no utilizar pegamento super rapido pues la juntura queda demasiado ura), luego coser con hilo y agnja para reforzar la union. Se puede utilizar una pinza dentada para comea sin fin para alinear perfectamente el espacio entre los dientes de los dos extremos de la banda antes de pegarlos, Una vez con la banda dentada a la medida, alejando 0 acercando el conjunto de motor/soporte a lo largo del perfil en el cual estan montados. Mas informacion: ‘Automatizanos.com @antomatizanos Banda transportadora a la medida Para evitar el uso de tensionadores adicionales, se debera recurrir a un material bastante elastico para la confeccion de Ia banda, se puede usar un neumatico viejo, ( de ser posible de auto y entre mas grande mejor ) esto garantizara que la superficie de la banda sea lo mas regular y plana posible. Otra altemativa esteticamente mas agradable, pero mucho menos resistente, seria utilizar una banda elastica usada para ejercicios 0 yoga. Se debera calcular la longitud de la banda, para que sea un poco mas pequeiia que la distancia entre los ejes mas alejados, de forma que esta se tensione sola. Para pegar los extremos de la banda, se recomienda usar un pegamento para caucho ( de nuevo, no usar pegamento super rapido, pues la juntura quedaria demasiado dura), y realizar los cortes de los extremos de la banda en un angulo aproximado de 45 grados, de esta forma se obtiene una menor resistencia y movimiento de la banda mas suave cuando la juntura se aproxima a alguno de los ejes. Sy Sie CONTROL DE VELOCIDAD CON ARDUINO El control de velocidad esta concebido para un motor paso a paso de hasta 2 Amperios usando un modulo A4988. Se utiliza un Arduino Nano para realizar la automatizacion de la banda. Se tienen los siguientes controles: + Display de 7 segmentos y 3 digitos multiplexado que muestra la velocidad de la banda en RPM ademas de algunos otros mensajes + Parada de emergencia, una vez pulsado solo se puede sacar de este estado desactivando mecanicamente el interruptor y poniendo el control de velocidad a 0. + Control de velocidad. se puede modificar la velocidad desde 0 hasta 300 RPM aproximadamente + Selector de direccion de la banda. Mas informacion: ‘Automatizanos.com @antomatizanos El circuito se monto en una tarjeta de circuito impreso universal y dentro de una caja plastica que puede ser sujetada a la estructura de la banda, usando tomillos y tuercas en T debidamente introducidas al perfil El sistema se puede alimentar con una tension entre 14-26V y posee un diodo para proteccion de inversion de polaridad. Se agrego una base para un integrada RS-485 que va conectado a los pines RX y TX del arduino para una futura expansion para control y mouitoreo remoto. PRUEBAS Y CONCLUSIONES, + Se realizaron pruebas con tapas de refrescos como objetos transportados en la banda, Si se quieren mover objetos con mayor peso © un poco mas alto, se deberé adicionar rodillos para oforgarle mas estabilidad a estos. + Para mejorar un poco la traccion se puede agregar algun material que aporte friecion al eje que esta conectado al motor, como por ejeniplo un poco de recubrimiento termoencogible. + Enrevoluciones mmy bajas del motor se observan vibraciones considerables, este es un fenomeno que ocurre en los motores de paso, cuando la frecuencia con que se entregan Jos pulsos se acerca a su frecuencia de resonancia natural. Probablemente se debera adicionar algunas juntas de goma entre el motor y en las patas para minimizarlas. + La corriente maxima del motor usado es de 1.2 Amperios, por lo tanto se fijo la corriente maxima a entregar por el modulo A4988 en 1 Amperio, ademas este es el valor maximo recomendado si no se utiliza algun medio de enfriamiento adicional al modulo, + Para una parada de emergencia aun mas efectiva, se podria eablear en serie el contacto normalmente cerrado (N.C) de la parada de emergencia con el voltaje de alimentacion del Mas informacion: ‘Automatizanos.com @antomatizanos motor, de esta forma aun cuando el arduino no responda a Ja detencion del motor este dejara de moverse por falta de electricidad. + Elenvio de pulsos al modulo 44988 se implemento usando la fincion tone() del Arduino, esto hace que la frecuencia mas baja que se pueda enviar al motor es de aproximadamente 30 Hz. ENLACES Video demostrativo del ensamblaje de los distintos elementos, ademas de las pruebas realizadas https://youtu.be/TYceTGFZKB8. Arduino Nano Clon: http://s.click-aliexpress.com/e/jYRZRZN Perfil de aluminio extruido 2020 ranurado en T "largos" : htt gR3{Gie6i Perfil de aluminio extruido 2020 ranurado en T "cortos" : http eUrrbEe Angulo interno en forma de L y tornillos prisioneros con cabeza allen : http:// s.click.aliexpress.com/e/jIuNZRN Cojinete de sujeccién con rodamiento interno para varilla de Smum : hetp:// s.click.aliexpress.com/e/MjY7YrV Tomillos cabeza hexagonal allen MS x 8 : http://s.click.aliexpress.com/e/r37eEEi ‘Twerca para ranura en T : http://s.click.aliexpress.com/e/QBUZI6i Ejes lisos en acero de §mm : http://s.click.aliexpress.com/e/ZnmMjQr Banda dentada GT2 : http://s.click.aliexpress.com/e/rB2VbaY Motor paso a paso NEMA 17 : http:/(s.click.aliexpress.com/e/Qf6M{Mn Soporte en angulo para motor paso a paso NEMA 17 : http://s.click.aliexpress.com/e/ZfeVVIu tomillos cabeza hexagonal allen M3 x 6 : http://s.click.aliexpress.com/e/3FUzfaM Polea dentada 16 dientes GT2 para motor Smm : http://s.click.aliexpress.com/e/JGE6Aim Polea dentada 20 dientes GT2 para ejes 8mm : http://s.click.aliexpress.com/e/aAmm2r Llaves hexagonales allen de 1.5.2 y 4mm: http://s.click.aliexpress.com/e/3FUbeqn Pinza dentada para correa sin fin: http://s.click.aliexpress.com/e/3JYtNrv Banda elastica usada para ejercicios o yoga: http://s.click.aliexpress.com/e/3nYFYJE Modulo manejador de motor paso a paso A4988: http://s.click.aliexpress.com/e/ney7eAE, s.click.aliexpress.com/e/ s.click.aliexpress.com/e/ ‘Automatizanos.com @antomatizanos ESQUEMATICO DEL CIRCUITO DE CONTROL DE VELOCIDAD DE BANDA, TRANSPORTADORA PARA MOTOR PASO A PASO CON VISUALIZACION EN DISPLAY DE 7 SEGMENTOS 3 DIGITOS CON INTERRUPTOR DE PARADA DE EMERGENCTA, DIRECCION Y AJUSTE DE VELOCIDAD [area ft ‘Automatizanos.com @antomatizanos CODFIGO FUENTE ARDUINO PARA CONTROL BANDA TRANSPORTADORA CON MOTOR PASO A PASO VISUALIZACION EN DISPLAY MULTIPLEXADO DE 7 SEGMENTOS 3 DIGITOS, CONTROLES DE PARADA DIRECCION Y VELOCIDAD 1] OOS II III ASIII AISI aw Automatizanos.com aw // Control de velocidad para banda transportadora 7/ con motor paso a paso, modulo 44988 y display de 7 segmentos 7/1 de 3 digitos multiplexados. Panel de control con interruptor //_ de parada de emergencia, selector de direccion y potenciomentro para velocidad [POPE EOC EEO DORE ECC ROE DOE C CECE pr DISPLAY 7 SEGMENTOS 3 DIGITOS REF 5631S CATODO COMUN A FG) B E}|c + DP D / #include // pines del display de 7 segmentos 3 digitos int sega = 9; int segb = 7; int segc = 3; int segd = 5; int sege = 6; int segt = 8; int segg = 2; int segp = 4; int digitl = 10; int digit2 $ int digit3 = 12; // module manejado de motor paso a paso Agg8a #define StepperPulse AL #define StepperDir 0 define StepsRev 200 #define MaxFreq 1060 define FWD 6 Mas informacion: ‘Automatizanos.com @antomatizanos define REV 1 // panel de control #define Estop 22 #define Direction a3 int Potentioneter = 4; int ToneFreqMin = 31;/ //Limite inferior para tone() !! SevenSeg disp( sega, segb, segc, sead, sege, segt, segg ): const int numOfDigits = 3; int digitPins[nunOfDigits] { digitl, digit2, digit3 int firstboot; int emergencystop; int directionstop; int lastdirection; int potvalue; int RPM; unsigned int FREQ; void setup() { JJ Configuracion del Display pinMode(sega, OUTPUT); pinlode(segb, OUTPUT) ; pinMode(sege, OUTPUT) ; pinode(segd, OUTPUT) ; pinlode(sege, OUTPUT) ; pinMode(segf, OUTPUT) ; pintode(segg, OUTPUT) ; PinHode(segp, OUTPUT) ; pinMode(digit1, OUTPUT) ; PinMlode(digit2, OUTPUT) ; PinMode(digit3, OUTPUT) ; disp, setDPPin(segp) ; disp, setCommonCathode(); disp.setDigitPins( numOfDigits, digitPins ); disp.setTimer(1); // No usar con funciones de servo al mismo tiempo! //disp.setTimer(2); // No usar con funcion tone() al mismo tiempo! disp. startTimer(); // Configuracion de pines del modulo de motor paso a paso Adg88 pinMode (StepperPulse, OUTPUT) ; pinMode(StepperDir, OUTPUT); // Configuracion de pines del panel de control pinMlode(Estop, INPUT); pinMlode(Direction, INPUT); digitalWrite(Estop, HIGH); // PullUp activado Mas inform: ‘Automatizanos.com @antomatizanos digitalWrite(Direction, HIGH); // PullUp activado + 71 ciclo infinito: void loop() { if (firstboot){ digitalWrite(StepperPulse, LOW) ; digitalWrite(StepperDir, FWD); lastdirection=REV; noTone(StepperPulse) ; disp.write("8.8.8."); delay (500) ; disp.write(""); delay (500) ; disp.write("ON"); delay (509) ; disp.write(" delay (500) ; disp.write("ON*); delay (500) ; disp.write(""); delay (509) ; firstboo + potvalue = analogRead(Potentiometer) ; FREQ = map(potvalue, 0, 1023, 0, MaxFreq); // Pone en VERDADERO emergencystop cuando se presiona el interruptor de parada if( digitalRead(Estop) == 1 ){ emergencystop = 1; 71 Detiene el motor y muestra el mensaje if(emergencystop == 1){ noTone(StepperPulse) ; disp.write("Est"); + // Para salir del estado de parada de emergencia, se debe halar el interruptor y poner el potenciomentro en velocidad cero if(digitalRead(Estop) == 0 & emergencystop == 1 && FREQ < ToneFregMin ){ emergencystop =0; /1 Cambio de Direccion if(digitalRead (Direction) == FWD && lastdirection REV) { Mas informacion: ‘Automatizanos.com @antomatizanos noTone(StepperPulse) ; digitalWrite(StepperDir, FWD); lastdirection = FWD; + if (digitalRead (Direction) noTone(StepperPulse) ; digitalWrite(StepperDir, REV); lastdirection = REV; } = REV && lastdirection == FWD){ // Actualizar 1a Lectura de Revoluciones Por Minuto (RPM) if(emergencystop != 1 ){ if( FREQ < ToneFreqHin){ RPM = 0; noTone(StepperPulse) ; } else { RPM = (FREQ *60 / StepsRev ) ; tone(StepperPulse, FREQ) ; } disp.write(RPM) ; } ISR(TIMER1_CONPA_vect) { disp. interruptAction(); + Mas informacion: ‘Automatizanos.com @antomatizanos SevenSeg.h * SevenSeg v1.1 SevenSeg.h - Library for controlling a 7-segment LCD Created by Sigvald Marholm, 02.06.2015. ” #ifndet SevenSeg_h define SevenSeg_h #include “Arduino.h" class SevenSeg { public Z/ Constructor SevenSeg(int, int, int,int,int, int, int) ; // Low level functions for initializing hardware void setCommonanode(); void setCommonCathode() ; void setDigitPins(int, int *); void setActivePinState(int, int) ; void setDPPin (int); void setColonPin(int) ; void setSymbPins (int, int, int, int) ; J/ Low level functions for printing to display void clearDisp(); void changeDaigit (int) ; void changeDigit (char) ; void writeDigit(int); void writeDigit(char); void setDP(); void clearDP(); void setColon(}; void clearColon(); void setApos(); void clearApos(); // Low level functions for controlling multiplexing void setDigitDelay(long int); // Should I have this function? void setRefreshRate (int) ; void setDutyCycle(int) ; J/ High level functions for printing to display void write(tong int); void write(int) ; void write(tong int, int); void write(int, int); void write(char*); Mas inform: ‘Automatizanos.com @antomatizanos void write(String) ; void write(doubte) ; void write(double num, int point); void writeClock(int, int, char) ; void writeClock(int, int) ; void writeClock(int char}; void writeClock( int); // Timer control functions void setTimer(int); void clearTimer(); void interruptAction(); void startTimer(); void stopTimer() ; // To clean up //_ void setPinState(int); | // I think this isn't in use. Its called setActivePinState? // int getDigitDelay(); // How many get-functions should I make? private: // The pins for each of the seven segments (eight with decimal point) int _A; int 7B: ant TC; ant ID; int 7E; int TF; int 16; int "DP; // -1 when decimal point not assigned // Nariables used for colon and apostrophe symbols int _colonState; // Whether colon is on (_segOn) or off (_seg0ff) int TaposState;_ —// Whether apostorphe is on (_segOn) or off (_segOff). int “colonSegPin; int “cotonSegLPin; int “aposSegPin; int “symbDigPin; /* The colon/apostrophe handling needs some further explanation: * colonSegPin is the segment pin for colon. I.e. some displays have a separate segment for colon on one of the digits. * others have colon split across two digits: i.e. the upper part has a separate segment on one digit, whereas the lower * part has uses the same segment pin but on another digit. It is assumed that this segment pin is only used for colon, * and it is stored into colonSegPin by SetColonPin(int). The functions setColon() and clearColon() turns on/off this pin, * respectively. * On some displays, colon is one or two separate free-standing LED(s) with its own cathode and anode. In case of common Mas inform: ‘Automatizanos.com @antomatizanos * cathode, ground the cathod and treat the anode(s) as a segment pin. The other way around in case of common anode. This * should make the method described above applicable. * On other displays, the upper colon part, the lower colon part, as well as an apostrophe, shares segments with the usual * segments (i.e. segments A, B and C) but is treated as a separate symbol digit that must be miltiplexed along with the * other digits. In this case the function setSymbPins(int,int,int, int) is used to assign a pin to that digit, stored in * symbDigPin. The pin corresponding to the upper colon segment is stored in colonSegPin, whereas the lower colon segment * is stored in colonSegLPin. aposSegPin holds the segment pin for the apostrophe. symbDigPin being unequal to -1 is an * indication for multiplexing-related functions that it must miltiplex over _numOfDigits+l digit pins. In this case, the ¥ setColon(), clearColon(), setApos() and clearApos() does not directly influence the pin, but the variable colonState and * aposState. In this case, the digit mist be changed to the symbol digit by issuing changeDigit('s') in order to show the * symbols. / // The pins for each of the digits int * dig; int _numOfDigits; // Timing variables. Stored in microseconds. long int _digitDelay; 7/ How much time spent per display during multiplexing long int _digitOnDelay; 7/ How much on-time per display (used for dimming), i.e, it could be on only 40% of digitDelay long int _digitOffDelay; // digitDelay minus digitOnDelay int _dutyZycle; // The duty cycle (digitOnDelay/digitDelay, here in percent) // Strictly speaking, _digitOnDelay and _digitOffDelay holds redundant information, but are stored so the computations only // needs to be made once. There's an internal update function to update them based on the _digitDelay and _dutyCycle void updDelay(); void execDelay (int); // Executes delay in microseconds char iaExtractDigit(Long int, int, int); long int ialimitint(Long int); // Sets which values (HIGH or LOW) pins should have to turn on/off segments or digits. J/ This depends on whether the display is Common Anode or Common Cathode int _digOn; int “aigott; int “segOn; int Tseg0ff; // Variables used by interrupt service routine to keep track of stuff Mas inform: ‘Automatizanos.com @antomatizanos int _timerDigit; // What digit interrupt timer should update next time int _timerPhase; // Mat phase of the cycle it is to update, i.e. phase 1 Ton), or phase © (off). Needed for duty cycling int _timerID; 7/ Nalues 0,1,2 corresponds to using timerd, timerl or timer2 ‘long int _timerCounter; J/ Prescaler of 64 is used since this is available on all timers (0, 1 and 2) // Timer registers are not sufficiently large. This counter variable will extend upon the original timer. 17 and increment by one each time long int _timerCounterOnEnd; — // How far _timerCounter should count to provide a delay approximately equal to _digitOndelay long int timerCounterOffend; // How far _timerCounter should count to provide a delay approximately equal to _digitoffDelay // What is to be printed by interruptAction is determined by these variables ‘long int _writeint; // Holds the number to be written in case of int, fixed point, or clock int _writePoint; // Holds the number of digits to use as decimals in case Of fixed point “1 float _writeFloat; // Holds the float to write in case of float. OBSOLETE: Float are converted to fixed point char *_writestr; // Holds a pointer to a string to write in case of string char _writelfode; // ‘p' for fixed point, ‘i! for integer, ‘f' for float, ':7/'.'/'_' for clock with according divisor symbol String _writeStr0bj; yi tendif ‘Automatizanos.com @antomatizanos Mas informacion: ‘Automatizanos.com @antomatizanos SevenSeg.cpp * SevenSeg v.1.0 SevenSeg.h - Library for controlling a 7-segment display Created by Sigvald Marholm, 62.06.2015 / #include “Arduino. h” #include "SevenSeg.h" 77 Constructor SevenSeg: :SevenSeg(int A,int B,int C,int D,int E,int F,int G){ // Assume Common Anode (user must change this if false) setCommonAnode() ; // Set segment pins Aza. 1; // DP initially not assigned // Set all segment pins as outputs pinllode(_A, OUTPUT) ; Pinlode(B, OUTPUT) ; Pinlode(“C, OUTPUT) ; pinllode("D, OUTPUT) ; pinlode(E, OUTPUT) ; Pinlode(“F, OUTPUT) ; pinMode(—G, OUTPUT) ; // Assume no digit pins are used (i.e. it's only one hardwired digit) _nunOfDigits=0; _colonState=_seg0ff; // default off TaposState= SegOff; // default off TcolonSegPin=-1; 77 -Lwhen not assigned TcolonSeglPin=-1; _// -1 when not assigned TaposSegPin=-1; // -1 when not assigned TsymbDigPin=-1; // -1 when not assigned // When no pins are used you need not multiplex the output and the delay is superfluous 77 TBD: Needed for duty cycle control. Add option to differentiate between © and 1 digit pins _digitDela: Tdigi tonDeLay: Tigi tO fDetay= TdutyCycle=100; Mas inform: ‘Automatizanos.com @antomatizanos // Timer data (default values when no timer is assigned) _timerDigit=0; TtimerPhase=1; TtimerID=-1; TtimerCounter=0; TtimerCounterOnénd=0; a // Clear display clearDisp(); + void SevenSeg: :setTimer(int timerID){ 7 Assigns timerO, timer] or timer2 solely to the task of multiplexing the display (depending on the value of timerNumber) For an example of a § digit display with 100Hz refresh rate and able to resolve duty cycle in 10%-steps a timing of the following resolution is needed: 1/( loaHz * 5 digits * 0.1 ) = 206us It is sufficient, but the brightness should be adjustable to more than 10 values. Hence a resolution of I6us is selected by setting the prescaler to 64 and the compare register to 3: interrupt delay = (64*(3+1))/16"Hz = 16us The timerCounter variable is of type unsigned int having a maximum value of 65535. Incrementing this at each interrupt and taking action upon timerCounterOnEnd or timerCounterOff€nd yields a maximum delay for something to happen: max delay for something to happen = léus * (65535+1) = 1.045 which should be more than sufficient if you want to be able to look at your display. oi _timerID = timerID; ‘Automatizanos.com @antomatizanos void SevenSeg: :clearTimer(){ } stopTimer(); “tinerID = “1; void SevenSeg: :startTimer(){ ? void SevenSe cli(); // Temporarily stop interrupts // See registers in ATmega328 datasheet if ( timer TECROA TCCROB TCNTO OCROA 3 TCCROA |=" (1< (10° _numOfDigits-1) or num < (10° (numOfDigits-1)41) // Store these values in object during digit pin assignment to save computation? * ‘Display a positive or negative overload * else display can handle nunber * num = 2468 // example * digit_0 = num / (10°(_numofDigits-1)) 122 * digit™1 = (num / (10°(_numOfDigits-2)))%10 Wa * ith digit = (num / (18*(_numOfDigits-1-i)))%10 7 6 and 8 for i=2 and3 * IMPROVED: * num = 2468 J) exampmle * — digit_@ = num % 10; * num /= 10; Mas inform: ‘Automatizanos.com @antomatizanos digit_1 = num % 10; num /= 10; * FIXED POINT: * write similar to int, but write fp at correct position. * num=1234, and fp=0 => 1234 (don't show .) * num=1234, and fp=1 => 123.4 * num=1234, and fp=4 => 0.123 (option 1, too unpredictable and heavy) * num=1234, and fp=4 => 1234 (simply don't show fp as it's invalid) writeClock(int ss){ writeClock(ss/60, 58%60) ; + void SevenSeg: :writeClock(int ss, char c){ writeClock(s5/60,53%60,c); + void SevenSeg: :writeClock(int mm, int ss){ // Use ':' if assigned, '.' otherwise, or simply nothing if none assigned if (_colonSegPin!=-1){ writeClock(mm,ss,":'); } else if(_DP!=-1){ writeClock(nm,ss, } else { writeClock(mm, ss, '_ void SevenSeg::writeClock(int mm, int ss, char ¢){ if(_timerID==-1){ // No timer assigned. MUX once int num = mm*100+ss; // colon through symbpin? 1 if yes int symbColon = (_symbDigPin!=-1); for(int iz numOfDigits-1;i>=0;i--){ changeDigit (i); int nextDigit = num % 10; writeDigit (nextDigit) ; // Possible future update: don't write insignificant zeroes if( *:" && IsymbColon) setColon(); ‘Automatizanos.com @antomatizanos _numOfDigits-3)) setDP(); // Only set " in the right place execDelayi_digitOnDeLay); if(cs=':' E& IsymbColon) clearCoton(); =") clearDP(); writeDigit(’ "); execDelay(_digit0ffDelay) ; } if(symbColon && changeDigit('s'); setColon(); execDelay(_digitOnDelay) ; clearColon() ; execDelay(_digitOffDelay) ; + } else { it _Writelfodesc; LwriteInt=mm*100+ss ; + void SevenSeg: :write(int num,int point) { write((tong int)num, point) ; ? void SevenSeg: :write(long int num,int point){ if(_timerTD==-1){ // No timer assigned. NUX once // Compute the maximum positive and negative numbers possible to display // (TBD: Move this to a computation done on pin assignments?) Yong int maxllegNum=1; for(int numOfDigits-1;i++) maxtlegNum*=10; long int maxPosilum=10*maxllegNum-1; maxNegNum=-maxilegtlum+d ; J/ TBD: Change to displaying OL (overload) or if(nummaxPosNum) num=maxPosNum; if (numemaxNlegNum) num=maxNegNum; - or similar? if(point==0){ __// Don't display decimal point if zero decimals used umOfDigits; 71 value if-sentence won't trigger on numOfDigits-point-1; // Map number of decimal points to digit J/ TBD: Fix minus Mas inform: ‘Automatizanos.com @antomatizanos int minus= if (num) { /* USED IN v1.9 - DOESN'T SUPPRESS LEADING ZEROS for(int iz numOfDigits-1;i>=9;1--){ changeDigit(i) ; int nextDigit = num % 10L; if(minus&&i==0) writeDigit('-') else writeDigit(nextDigit) ; /{ TBD: Possible future update: don't write insignificant zeroes ) setDP(); execDelay(_digitOnDelay) ; writeDigit{’ *); clearDP(); execDelay(_digitOffDelay) ; “ for(int is_numOfDigits-1;i>=0;i--){ changeDigit (i); Ant nextDigit = num % 19L; if (num || i>point-1 || i== numOfDigits-1){ writeDigit(nextDigit) ; } else if(minus){ writeDigit('-"); minus=0; } else { writeDigit(’ ? if (poin num /= 10; execDelay(_digitOnDelay) ; writeDigit(’ "); clearDP(); execDelay (_digit0ffDelay) ; % i) setDP(); } }else { // Use timer if(point==0){ __// Don't display decimal point if zero decimals used umOFDigits; // value if-sentence won't trigger on umOfDigits-point-1; // Map number of decimal points to digit awriteHode = 'p'; // Tell interruptAction that write(int, int) was used (fixed point). ‘Automatizanos.com @antomatizanos _writeInt = ialimitInt(num); // Tell interruptAction to write this number + } _writePoint = point; // ... with this fixed point // Extracts digit number “digit" from “number” for use with ia - interruptaction char SevenSeg: :iaExtractDigit(long int number, int digit, int point){ /* OLD VERSION WITHOU ZERO SUPPRESION (v1.0) if (number<0) { if(digit=-0) return *-"; number*=-1; + for(int i=0;i< numOfDigits-digit-1;i++) number/=10L; return (char) ({number%1L)+48L) ; “/ long int old_number = number; int minus = 0; if (number<0) { number minus + if (digit !=_numofDigits-1){ for(int T=0;i< numOfDigits-digit-1;it+) number/=10L; + if(digitspoint-1 || digi ((number%10L)#48L) ; else { if (iaExtractDigit (old_number, digit+1,point) (old_number,digit+1,point)!=" ° && minus) return } else return ' °; //, else if (iaExtractDigit (old_number,digit+1, point) numOfDigits-1 || number!=0) return (char) ' G& iaExtractDigit && minus) return // ‘else if(iaéxtractDigit(old_nunber,digit+1,point) && iaExtractDigit (old_number, digit+1,point)!='-" && minus) return '-"; M7 else '; i else if(iafxtractDigit (number, digit+1,point’ if(minus) return else return } else return ' '; y ? // Limits integer similar to how it's done in write(int, int) ont Mas inform: ‘Automatizanos.com @antomatizanos long int SevenSeg: :iaLimitInt(long int number) { // Compute the maximim positive and negative numbers possible to display // (TBD: Nove this to a computation done on pin assignments?) long int maxNegNum=1; for(int isl;ic= numOfDigits-1; i++) maxNegNum*=10; long int maxPosiium=10*maxNegNum-1; maxNegNum=-maxNlegtium+1; J/ TBD: Change to displaying OL (overload) or ---- or similar? if (numbersmaxPoslum) number=maxPostium; if (numbercmaxNegium) number=maxNegtum; return number; + void SevenSeg: :write(int num){ write((Long int)num) ; ? void SevenSeg: :write(long int num){ if(_timerID==-1){ // No timer assigned. MUX once write (num, 9); }else { // Use timer _writeHlode = 'i'; // Tell interruptaction that write(int) is used. “writeInt = ialimitInt(num); // Tell interruptaction to write this int + i Void SevenSeg: :writeDisplay(int A,int B,int C,int D,int colon){ 71 Rewrite. Take caution to properly shut down all symbols for the duty cycle controt. // This can be done by turning off the digit rather than the symbol, but that does not 7/ work for symbols not connected to any digit (i.e. hardwired). Hence it should happen // at a segment level.x int digits[4]; digits [0 digits[1 digits [2 digits [3]=D; for(int is0;i< numOfDigits;i++){ ‘Automatizanos.com @antomatizanos if (_digitOnDetay!=0){ // delaylicroseconds() yields a large delay for some reason. Hence the if-sentence changeDigit (3); writeDigit (digits [i]); //3f (colon) setCoton(); delayHicroseconds(_digitOnDelay); // TBD: change to execDelay() } if (_digitOffDelay!=0){ // delayMicroseconds(@) yields a large delay for some reason. Hence the if-sentence changeDigit(' ‘) uariteDigit(' '); //clearColon(); delaylicroseconds (_digitOtfDelay) ;// TBD: change to execDelay() + > + sf void SevenSeg: :write(char *str){ if(_timerID==-1){ // No timer assigned. NUX once int i=; int j=0; clearCoton(); white(str[i] !='\0"){ changeDigit(3); writeDigit(str[il); if(str[isl]==".")4 setDP(); int; } execDelay(_digitOnDelay) ; writebigit{’ "); clearDP(); execDelay(_digitOffDelay) ; ity + }else { // Use timer _writeHlode = 's'; // Tell interruptAction that write(char*) is used. “writeStr = str; // Tell interruptAction to write this string } void SevenSeg: :write(String str){ if(_timerID==-1){ // No timer assigned. MUX once int i=0; int j=0; clearCoton(); ‘Automatizanos.com @antomatizanos Mas inform: + while(icstr.length()){ changeDigit (3); writeDigit (str[i]); if(str(asl}==".'){ setDP(); itt; } execDelay(_digitOnDelay) ; writeDigitl’ "); clearDP(); execDelay(_digitOffDelay) ; ist; ie } }else { // Use timer _writeHlode = ‘0’; // Tell interruptAction that write(String) is used. “writeStrObj = str; // Tell interruptAction to write this string void SevenSeg: :write(double num, int point){ } for(int is0;i=0.5 && num>0) intNume+; if(remainder<=0.5 && nummaxPosNum) num=maxPosNum; if(numemaxllegNum) num=maxNegNum; int point=9; if (numeO&&num>-1) { while (num*100<=maxPosNum && num*106: num*=10; point++; iaxNegNum && point<_numOfDigits-2){ if ( (int) num==0) { point++; // The minus sign will disappear t Mas inform: ‘Automatizanos.com @antomatizanos } else if (numO6Snumel){ while (num*100<=maxPosNum && num*106: num*=10; point++; i } else { while (num*10c=maxPosNum && num*10>=maxNegNum) { num*=10; point++; } ? 7/ Implementing correct round-off double rest=num; if(rest<0) rest*=-1; rest=rest-(1ong int)rest; if(rest>=0.5&6num>0) numi+ if(rest>=0,5&Snum<®) num snaxNeghum & point<_numOfDigits-1){ if (_timer ID: Dt write((long int)num, point); }else { // user timer // Adapting to another format point=point+1-_numOfDigits; _writeHlode='*"; LwritePoint=-point; TwriteInt=(Long int)num; + void SevenSeg: :updDelay(){ // On-time for each display is total time spent per digit times the duty cycle. The // off-time is the rest of the cycle for the given display. long int temp = _digitDelay; // Stored into long int since temporary variable gets larger than 32767 temo “= _dutyCycle; 7/ Wultiplication in this way to prevent multiplying two "shorter" ints. tem /= 101 minimize round-off errors _digi tOnDelay=temp TdigitOffDelay=_digitDelay-_digitOnDelay; // Division after multiplication to if (_timerID!=-1)¢ /7 Artefacts in duty cycle control appeared when these values changed while interrupts happening (A kind of stepping in brightness appeared) eli); Mas inform: ‘Automatizanos.com @antomatizanos _timerCounterOnEnd=(_digitOnDelay/16) -1; “timerCounterOffEnd=(_digitOftDelay/16) -1; If (_digitOnDelay==0) “timerCounterOnEnd if (“digi tOffDeLay==0)”_timerCounterOffEnd=0; _timerCounter=0; Sei); } + void SevenSeg: :interruptAction(){ // Increment the library's counter _timerCounter++; // Finished with on-part. Turn off digit, and switch to the off-phase (_timerPhase=0) if ( (_timerCounter>=_timerCounterOnEnd)&&(_timerPhase==1) ){ _timerCounter=0; “timerPhase: writeDigit(* // Ifa write mode using . is used it is reasonable to assume that DP exists. Clear it (eventhough it might not be on this digit) if (_weiteNlodes='p' | |_writelode: "s"| |_writeNodess'f") clearbPT); if (_writeHode==':') clearColon(); ? // Finished with the off-part. Switch to next digit and turn it on if((_timerCounter>=_timerCounterOffEnd)&&(_timerPhase==0) ){ _timerCounter=0; TtimerPhase=1; _timerDigit++; //3f (_timerDigit: if (_timerDigit>=_numOfDigits){ if(_symbDigPinT=-1 && _timerDigit==_numOfDigits){ // Symbol pin in use. Let _timerDigit=_num0fDigits be used for symbol mux } else { /7 Finished mixing symbol digit, or symbol pin not in use _timerDigit=0; + + if(_timerDigit==_numOfDigits) changeDigit('s'); else changeDigit(_timerDigit) ; /] — writeDigit (_tinérDigit) ; numOfDigits) _timerDigit=0; if(_writeode=="p'| |_writeMode=='t'){ // Fixed point writing (or float) writeDigit (iaxtractDigit (_writeInt,_timerDigit, writePoint)); if(_writePoint==timerDigit) setDP()7 + Mas inform: ‘Automatizanos.com @antomatizanos if (_writeMode=='i'){ // Fixed point writing WriteDigit (iaExtractDigit (_writelnt, _timerDigit,_numOfDigits) ); + if (_writeModess':' | |_writeModess'.' | |_writeModes='_'){ // colon through symbpin? 1 if yes int symbColon = (_symbDigPin!=-1); if(_timerDigit==_numOfDigits){ J7 Symbol digit setColon(); } else { writeDigit (LaextractDigit (_writelnt,_timerDigit, numOfDigits) ); if (_writelod && 'symbColon) setColon(); if ((_writellode=='.')&&(_timerDigit==numOfDigits-3)) setDP(); // Only set "." in the right place + + if (_writeNlodes='s'){ // This algorithm must count to the correct letter i in writeStr for digit j, since the two may be unmatched 7/ and it is impossible to know which letter to write without counting int 1-0; // which digit int j=0; // which digit have it counted to while(_writeStr[i]!="\O' && j<_timerDigit){ if (_writeStr[i+l]==".'){ i + int; jes + \riteDigit(_writeStr[i]); if(_writeStr[itl]==".") setDP(); } if (_writeNode=='o'){ J/ This algorithm must count to the correct letter i in _writeStr for digit j, since the two may be unmatched // and it is impossible to know which letter to write without counting int 77 which digit int j=0; // which digit have it counted to while(i< writeStrObj.length() && j<_timerDigit){ if (_writeStrObj[itl]==".'){ im; ? ist; jet t Mas inform: ‘Automatizanos.com @antomatizanos writeDigit(_writestrobj[i]); if(_writeStr0bj[itl]==".") setDP(); B 7] If we're in the on-part of the cycle and has counted as many interrupts corresponding to one on-phase if((_timerCounter>=_timerCounterOnEnd) && (_timerPhase==1) ){ _timerCounter: // Reset the library's counter TtimerPhase=0; 1 Suitch to off-phase // Turn off this digit writeDigit(' '); ¥ // Similar for the off-phase. if((_timerCounter>=_timerCounterOftEnd) && (_timerPhase==0) ){ _timerCounter=0; TtimerPhase: // Turn on the next digit _timerDigit++; It (_timerDigit: _TimerDigit=0; _numOfDigits) { } changeDigit(_timerDigit) ; writeDigit(_timerDigit) ; / pf void SevenSeg: :setDigitPins(int num0fDigits, int =pDigitPins){ if (_numofDigits>0){ // “delete [] _dig; free(_dig); , _numOfDigits = numofDigits; /J dig = new int[nunOtDigits] ; _dig = (int*)malloc (_numOfDigits * sizeof (int)); 77 mencpy(_dig, pDigitPins, numOfDigits); for(int i=0;i< numOfDigits;i++){ _diglil=pbigitPins[il; + ‘Automatizanos.com @antomatizanos Mas inform: + 4 void SevenSeg: :changeDigit(int digit){ // Turn off all digits/segments first. 7/ If you swith on a new digit before turning of 7/ @ slight shine of the “old” number in the “ne clearDisp(); digitalWrite(_digldigit], _digOn); the segments you will get digit. } void SevenSeg: :changeDigit (char digit){ if(digit=='s'){ 7/ change to the symbol digit clearDisp(); digitalWrite(_symbDigPin, _digOn); digitalWrite(_colonSegPin, _colonState) ; digitalWrite(_colonSegLPin, _colonState) digitalWrite(_aposSegPin, _aposState) ; } if(digite' '){ clearDisp(); + , void SevenSeg::setDPPin(int DPPin) { _DP=DPPin; BinMode(_DP, OUTPUT) ; void SevenSeg: :setDP(){ digitalWrite(_DP, _seg0n); } void SevenSeg: :clearDP(){ digitalWrite(_DP, _segOff); } y* void setDPPin(int); void setDP(); void clearDP(); ‘Automatizanos.com @antomatizanos Characters: Colon, apostrophe, comma(DP), randomly assignable symbols? Nost symbols can be confined to one character, but colon should be able to assign in two parts (UC and LC). Yet two colons are also present on some displays. And on some displays, colons and apostorphes are treated as a separate digit using an additional common cathode/anode. I've decided to treat the symbols in the following way OP is assigned as an eight segment for each digit, as this is the only way I've seen it done. Simple I want the functions setDPPin(int), setDP(), clearDP(). DP should be cleared at_each changeDigit (i.e. in ClearDisp?) In the parsing function it should be possible to write "1.2.3.4, Colon are treated in many different ways on many different displays. I want a function setColonPin() that are overloaded and take most of the case. setColon() and clearColon() should turn it on or off. I'U1 explain the scenarios, and the syntax: Colon may be split in two parts UC (upper colon) and LC (lower colon) or colon may be hardwired as one LED 1. Colon has its own cathodes and anodes. Ground the cathode if common cathode or tie anode to supply in case of common anode. Syntax: setColonPin(segPin) where segPin is the other pin. In this case the colon needs not be multiplexed. If split segment pin for UC/LC, the user joins them together. setColon()/clearColon() writes directly to segmentPin. 2. UC/LC is joined together using its own segment pin, and shares common anode/cathode with one of the digits Syntax: setColonPin(segPin,digPin). The function will detect at what digit to type the colon based on digitPin, and store this in colonDigl and colonDigl. If no digit is tied to digitPin issue an error. colonState is a private menber variable being set or cleared by setColon()/clearColon() writeDigit() checks colonState when on colonDig¥ or colonDigl digits and writes accordingly. 3. UC shares common anode/cathode digit pin with one of the digits, while LC shares with another digit. They are the same segment pin. Syntax: setColonPin(segPin,digLPin,digUPin). This works in the same way as above, except that different values are stored to DigU and DigL. 4. UC and LC are treated Like seperate segments on a new "symbol" digit pin(!). In these cases there is usually also an apostrophe (A) segment The UC and LC segments should be joined together into one segment (C) Syntax: setSymbolPin(SegCPin,SegAPin,digPin) digPin will be stored to symbDigPin, and the multiplexing must occur’ over one additional digit. This implies modification to i.e. setRefreshRate, setDigitDelay and maybe other functions. All functions must be checked. Members needed in class private: colonState 71 _segOn or _segOff aposState; // _seg0n or _seg0tf. Mas inform: ‘Automatizanos.com @antomatizanos colonDigu; // Which digits to activate colon at (one digit for UC and one for LC) colonDigl; // colonDigU==colonDigl==-1 means that it is treated as a separate digit, case 1 or 4. (check negative numbers for int) symbDigPin; // If the colon is on a separate digit pin the symbol digit pin number is stored here. Otherwise, it is -1. Non-zero values imply more muxing colonSegPin; aposSegPin; public setColonPin(int) ; setColonPin (int, int) ; setColonPin(int, int, int) ; setSymbPin (int, int,int, int); setColon(); clearCoton(); setApos(); clearApos(); The parsing function should parse colon to off except when any colon present in string. Same with apostorphe. I.e, "34:07", I initially wanted to have support for two colons since you need that on a watch. However, I've settled on only one colon since there are almost none display available with two colons. If I find one, and will use one, I will simply duplicate the colon stuff in my class. Actually, cases 1, 2 and 3 can be joined together! The colon can be turned on irrespective of what digits they are on (at least as long as there are only one colon) This simplifies the class: private: colonState; —// _segOn or __seg0tt aposState; // _segOn or _seg0ff symbDigPin; // If the colon is on a separate digit pin the synbol digit pin number is stored here. Otherwise, it is -1. Non-zero values imply more muxing colonSegPin; aposSegPin; public: setColonPin(int) ; setSymbPin (int, int, int, int) ; setColon(); clearColon(); setApos(); clearApos(); */ void SevenSeg: :setColonPin(int colonPin){ _colonSegPin=colonPin; BinMode (_colonSegPin , OUTPUT) ; digitalwrite(_colonSegPin, _colonState) ; Mas inform: ‘Automatizanos.com @antomatizanos } void SevenSeg::setSymbPins(int digPin, int segUCPin, int segLCPin, int segAPin){ _colonSegPin=segUCPin; TcolonSegLPin=seglCPin; TaposSegPin=segAPin; “symbDigPin=digPin; BinMode (_coLonSegPin , OUTPUT) ; pinMode (_colonSegLPin , OUTPUT) ; pinMode (~aposSegPin, OUTPUT) ; pinMode (—symbDigPin, OUTPUT) ; digitalwrite(_colonSegPin, _colonState) ; digitalWrite(_colonSegLPin, _colonState) ; digitalWrite(_aposSegPin, _aposState) ; + ia The functions for setColon(), clearColon(), setApos(), clearApos() directly sets or clears the segment pins if no symbol pin is assigned. Since no symbol pin is assigned colon (apos isn't set) has a separate segment pin "Colon" and shares a digit pin with one or two other digits (in case it is split into UC and LC). In this case it makes sense to control it just Like other Segments; by setting and clearing the segment pin with setColon() or clearColon() after the correct digit is selected with changeDigit(). Compare with setDP()/clearDP() Furthermore, it is not necessary to identify WHICH digit the colon segments apply for since, if colon is turned on, one may simply switch fon’ the segment pin for all digits, Nothing will be tied to the colon segment pin for other digits than those it applies to, hence it is sufficient to initialize this kind of hardware with setColon(int colonPin). Sometimes, a colon is present as one or two complete stand-alone LEDs. In this case, the can be wired up into one of these configurations to work. In the other main case, a separate symbol pin is assigned for colon and apostrophe. This is actually an additional digit pin which must be muxed across. The segment pins are shared wath other segments such as A-G. This is a compact way of allowing many symbols (colon and apostrophe) while only adding one more pin. This configuration is programmed with setSymbPins(int digPin, int segUCPin, int seglCPin, int segAPin), where digPin is the symbol digit pin and the other pins are the pins used for segment UC, LC and apos If colon is present as one segment only, segUCPin and segULPin can be the same value. Sometimes, colon and apostorphe are present as stand-alone diodes with their own cathodes and anodes not being connected Mas inform: ‘Automatizanos.com @antomatizanos to anything else. In this case, join their cathodes or anodes (in case of common cathode or anode respectively) and connect their other terminal to one segment pin each to make the mentioned configuration. The behaviour set/clear behaviour of these digits are a bit different in this case. The set/clear-funciton only sets a flag to on or off. In order to type the characters you must mux to the symbol digit by issuing changeDigit('s'). This function will Light up the appropriate symbols in accordance with the flags 7 void Sevense: _colonState=_segOn; if (_symbDigPin==-1){ digitalwrite(_colonSegPin, _segOn); + setColon(){ + void SevenSeg: :clearCoton(){ Tf (_symbDigPin==-1){ digitalWrite(_colonSegPin, _seg0ff); + } void SevenSeg: :setApos(){ _aposState=_segd Tf (_symbDi gPin==-1){ digitalWrite(_aposSegPin, _seg0n); + } void SevenSeg: :clearApos(){ _aposState=_segOff; if (_symbDi gPin==-1){ digitalwrite(_aposSegPin, _seg0ff); + } void SevenSeg: :writeDigit(int digit){ // Turn off all LEDs first to avoid running current through too many LEDs at once digitalWrite(_A, _seg0ff); digitalwrite("B, “seg0tf); digitalWrite(“C, “seg0ff); digitalWrite("D, “seg0ff); digitalWrite("E, “seg0ff); digitalwrite(_F, —seg0ff); digitalWrite(_G, “seg0ff); if (digit==1){ digitalWrite(_B, _seg0n); Mas inform: ‘Automatizanos.com @antomatizanos digitalWrite(_C, _seg0n); ? if (digit==2){ digitalWrite(_A, _seg0n); digitalWrite(_B, digitalWrite( digitalWrite(-e, digitalWrite(_D, } if (digi 3){ seg0n); 'seg0n); 'seg0n) ; 'segOn); G, digitalwrite(_A, _seg0n); digitalwrite(_B, digitalwrite(_¢, digitalWrite(7C, 'seg0n); seg0n); 'segOn); digitalWrite(_D, “seg0n); + if (digi 4) { digitalWrite(_F, _segOn); digitalwrite( digitalWrite("8, digitalWrite(_C, } if (digit==5){ G, “seg0n); 'segOn); 'seg0n); digitalwrite(_A, _seg0n); digitalWrite(7F, digitalWrite(7¢, digitalWrite(7C, 'seg0n); 'seg0n); 'seg0n); digitalWrite(_D, _seg0n); ? if (digi 6) digitalWrite(_A, _segOn); digitalwrite(_F, digitalWrite(_£, digitalWrite(_D, digitalWrite(_C, digitalWrite(7s, } if (digit==7){ seg0n); segOn); seg0n) ; 'seg0n) ; 'seg0n); digitalWrite(_A, _seg0n); digitalwrite("B, “segon); digitalwrite(_C, “seg0n); + if (digi 8){ digitalWrite(_A, _segOn); digitalWrite(_B, digitalWrite("C, digitalwrite(_D, seg0n); 'segOn); seg0n); Mas informacion: ‘Automatizanos.com @antomatizanos digitalWrite(_E, _seg0n); digitalWrite(_F, —seg0n); digitalWrite(_G, “seg0n); + if (digit==9){ digitalwrite(_6, _seg0n); digitalWrite("F, “seg0n); digitalWrite("A, “segon); digitalwrite(_B, _segon); digitalWrite(=C, “seg0n); digitalWrite(_D, “seg0n); } if (digit==0){ digitalWrite(_A, _seg0n); digitalWrite(_B, —seg0n); digitalWrite(_C, _seg0n); digitalWrite("D, “seg0n); digitalWrite(_E, “seg0n); digitalWrite(_F, _seg0n); } void SevenSeg: :writeDigit(char digit){ // Turn off all LEDs first. digitalWrite(_A, _seg0ff); digitalWrite(_B, “seg0ff); digitalWrite("C, “seg0ff); digitalwrite(_D, _seg0tf); digitalWrite(_E, “seg0tf); digitalWrite("F, “seg0ff); digitalWrite(_6, “seg0ff); if(digit=="-"){ digitalWrite(_G, _seg0n); } if (digit=="\370"){ // ASCII digitalWrite(_A, _seg0n); digitalWrite(_8, —seg0n); digitalWrite(_F, “seg0n); digitalWrite(_6, “seg0n); } /J Digits are numbers if (digit>=4866digit<-57) // Digits are small caps letters 22) digit if (digit>=976&digit<=: “AL if (digi Run writeDigit(’ ‘) to clear digit. code 248 or degree symbol: Write with writeDigit(int) writeDigit (digit-48) ; Capitalize. 25 Mas informacion: ‘Automatizanos.com @antomatizanos digitalWrite(_A, _seg0n); digitalWrite(_B, —seg0n); digitalWrite(_C, _seg0n); digitalWrite("E, “seg0n); digitalWrite(_F, —seg0n); digitalWrite(_6, “seg0n); } if (digi "BL digitalwrite(_C, _seg0n); digitalWrite("D, “seg0n) ; digitalWrite("E, “seg0n); digitalWrite("F, "seg0n); digitalwrite(_6, _seg0n); + if (digit=='C'){ digitalwrite(_A, _seg0n); digitalWrite("D, “seg0n); digitalWrite(_E, “seg0n); digitalWrite(_F, _seg0n); ? if(digite='D"){ digitalWrite(_8, _seg0n); digitalWrite("C, “seg0n); digitalWrite(_D, “segQn); digitalWrite("E, “seg0n); digitalWrite("6, "seg0n); , if (digite='E"){ digitalwrite(_A, _seg0n); digitalWrite("D, “seg0n) digitalWrite(_E, —seg0n) digitalWrite(_F, _seg0n); digitalWrite(_G, “seg0n); + if (digit=='F'){ digitalWrite(_A, _seg0n); digitalWrite(_E, —seg0n); digitalWrite(_F, —seg0n); digitalWrite(_¢, “seg0n); + if (digi ot digitalWrite(_A, _seg0n); digitalwrite(_B, —seg0n); digitalWrite(_C, “seg0n); digitalWrite(_D, “seg0n); digitalWrite("E, “seg0n); digitalWrite(_G, _seg0n); Mas informacion: ‘Automatizanos.com @antomatizanos // TBD: Really write G like a9, when it can be written as almost 6? "7 digitalwrite(_A, _seg0n); digitalWrite(=C, “seg0n); digitalWrite("D, “seg0n); digitalWrite(_E, “seg0n); digitalwrite(_F, “seg0n); + if (digites'H'){ digitalWrite(_B, _seg0n); digitalWrite(_C, “seg0n); digitalwrite("E, “seg0n); digitalWrite(_F, —seg0n); digitalwrite(_¢, “seg0n); + if (digit=='I'){ digitalwrite(_E, _seg0n); digitalWrite(_F, —seg0n); } if(digit=='J'){ digitalWrite(_8, _seg0n); digitalWrite(_C, —seg0n); digitalWrite("D, “seg0n); digitalWrite(_e, “seg0n); t if (digit=='k"){ digitalWrite(_B, _seg0n); digitalwrite(_C, —seg0n); digitalWrite(_E, _seg0n); digitalWrite("F, “seg0n) digitalWrite(_6, —seg0n); + if(digit=='L"){ digitalwrite(_D, _seg0n); digitalWrite(_E, _seg0n); digitalWrite(_F, —seg0n); + if(digite='N'){ digitalWrite(_A, _segdn); digitalWrite(“C, “seg0n); digitalWrite("E, “seg0n); } if (digit=='N'){ digitalwrite(_C, _seg0n); digitalWrite(_E, _seg0n); digitalWrite("G, “seg0n); + Mas informacion: ‘Automatizanos.com @antomatizanos if(digit=='0'){ digitalwrite(_A, digitalWrite(7B, digitalwrite("c, digitalWrite(_D, digitalWrite(_€, digitalWrite(F, } if (digits='P'){ digitalWrite(_A, digitalwrite("8, digitalwrite(_e, digitalwrite(_F, digitalWrite(7s, + if(digit=="0'){ digitalWrite(_A, digitalWrite(_B, digitalWrite(_c, digitalWrite("F, digitalWrite(_s, } Af (digite='R'){ digitalWrite(_E, digitalWrite (6, ? if (digit=='S'){ digitalwrite(_A, digitalWrite(7C, digitalWrite(_D, digitalWrite(_F, digitalwrite(_s, + if (digit=='T'){ digitalWrite(_D, digitalWrite(_e, digitalWrite(_F, digitalWrite(7¢, + if (digites"U'){ digitalWrite(_B, digitalWrite("C, digitalWrite(_D, digitalwrite(_e, digitalWrite(_F, -seg0n) ; Tseg0n) ; segOn); seg0n); 'seg0n); 'seg0n); seg0n); 'segOn); 'seg0n); seg0n); 'segOn); seg0n); seg0n); 'seg0n); seg0n); seg0n); _seg0n) ; Tsegon) ; =segon) ; Tsegon) Tsegon) Tseg0n); “seg0n); _seg0n) ; Tseg0n) ; Tseg0n) ; Tseg0n) ; =seg0n) ; Tseg0n) ; Tsegon) ; Tseg0n); Tseg0n) ; Mas informacion: ‘Automatizanos.com @antomatizanos if(digit=='V'){ digitalWrite(_C, _segOn); digitalWrite(_D, _seg0n); digitalWrite("E, —seg0n); + if (digites'W'){ digitalWrite(_8, _segQn); digitalWrite("D, “seg0n); digitalWrite(_F, _seg0n); } if (digit=='x'){ digitalwrite(_B, _seg0n); digitalWrite(_c, “seg0n); digitalWrite("E, “seg0n); digitalWrite(_F, —seg0n); digitalWrite(_G, _seg0n); + if(digit=="Y"){ digitalwrite(_8, _seg0n); digitalWrite("C, “seg0n); digitalWrite(_D, _seg0n); digitalWrite(_F, —seg0n); digitalWrite(_G, “seg0n); + if(digit=='Z'){ digitalWrite(_A, _seg0n); digitalWrite("B, “seg0n); digitalwrite(_D, —seg0n); digitalWrite(_E, _seg0n); digitalWrite("6, “seg0n); + + void SevenSeg: :execDelay(int usec){ if(usec!=0){ // delay() and delayMicroseconds() don't handle 0 delay if(usec<=16383) __deLaylticroseconds (usec); // maximum value for delayHicroseconds(); else delay (usec/1000) ; Mas informacion: ‘Automatizanos.com @antomatizanos keywords.txt Sintenntenenenenenennenoenaneneneneete # SevenSeg v1.1 # keywords.txt - Syntax Coloring Map # Sascha Bruechert, 05.02.2015 sibedeeeneteeaeEbeemeenmmneEnnte tS seneenREtoEECMRERERNeRnEnmNR Enea # Datatypes (KEYWORD1) SieeeentenebeneHeEnEEnmEeCEneE Ente SevenSeg — KEYWORD1 sineeneennenEReEEnEeRnEnEnEREnEEEa # Methods and Functions (KEYWORD2) SLEEPER ER EUE HEATER TEER REE R HEA ES digitPins KEYWORD2 numOfDigits KEYWORD2 ## Low level functions for initializing hardware setCommonAnode KEYWORD2 setCommonCathode KEYWORD2 setDigitPins KEYWORD2 setActivePinState KEYWORD2 setDPPin KEYWORD2 setColonPin KEYWORD2 setSymbPins KEYWORD2 ## Low Level functions for printing to display clearDisp KEYWORD2 changeDigit KEYWORD2 writeDigit _KEYWORD2 setDP_KEYWORD2 clearDP KEYWORD2 setColon _KEYWORD2 clearColon KEYWORD2 setApos _KEYWORD2 ClearApos KEYWORD2 ## Low Level functions for controlling multiplexing setDigitDelay —_KEYWORD2 setRefreshRate KEYWORD2 setDutyCycle KEYWORD2 ## High level functions for printing to display write KEYWORD2 writeClock KEYWORD2 ## Timer control functions setTimer KEYWORD2 clearTimer KEYWORD2 startTimer KEYWORD2 stopTimer KEYWORD2 Mas inform: ‘Automatizanos.com @antomatizanos interruptAction KEYWORD2 sineennenenennneEnnEtenEEonneE Enea # Instances (KEYWORD2) ‘SIE EE sineeneeennennneneneenoueumnenananeeee # Constants (LITERAL1) sitesnnnenenenenenenneneenanenenneans ‘Automatizanos.com @antomatizanos

You might also like