diff --git a/README.md b/README.md index 5068d92..d197529 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ -# witty +# Witty support Libraries + +Arduino support libraries and demo code for Didels Witty 2WD balancing robot. + -Arduino support libraries and demo code for Didels Witty 2WD balancing robot. \ No newline at end of file diff --git a/docs/WittyQuickStartGuide.pdf b/docs/WittyQuickStartGuide.pdf new file mode 100644 index 0000000..bec4247 Binary files /dev/null and b/docs/WittyQuickStartGuide.pdf differ diff --git a/examples/WittyDemo2/DemoWittyPfm.h b/examples/WittyDemo2/DemoWittyPfm.h new file mode 100644 index 0000000..13f6a66 --- /dev/null +++ b/examples/WittyDemo2/DemoWittyPfm.h @@ -0,0 +1,32 @@ +//DemoWittyPfm.h #include "DemoWittyPfm.h" +// erreur d'avoir fusionner +#include "Pfm.h" +#include "Inter2.h" + +SetupInter2(); // set interrupts + #define D2 DelMs(1000) + #define D5 DelMs(50) + pfmL=2; pfmR=2; D2; + pfmL=-2; pfmR=-2; D2; + pfmL=0; pfmR=0; D2; + pfmL=80; pfmR=80; D5; + pfmL=0; pfmR=0; D2; + pfmL=-80; pfmR=-80; D5; + pfmL=0; pfmR=0; D2; + + #define MaxVit 40 + #define MaxVit2 10 +#define Dac DelMs(20) + for (pfmR=0; pfmR0; pfmR--) {pfmL=pfmR; Dac;} + for (pfmR=0; pfmR>-MaxVit; pfmR--) {pfmL=pfmR; Dac;} + for (pfmR=-MaxVit; pfmR<0; pfmR++) {pfmL=pfmR; Dac;} + D2; + #define Dacf DelMs(10) + for (pfmR=0; pfmR0; pfmR--) {pfmL=pfmR; Dacf;} + for (pfmR=0; pfmR>-MaxVit2; pfmR--) {pfmL=pfmR; Dacf;} + for (pfmR=-MaxVit2; pfmR<0; pfmR++) {pfmL=pfmR; Dacf;} + D2; + +//break, fin while diff --git a/examples/WittyDemo2/WittyDemo2.ino b/examples/WittyDemo2/WittyDemo2.ino new file mode 100644 index 0000000..c416dd3 --- /dev/null +++ b/examples/WittyDemo2/WittyDemo2.ino @@ -0,0 +1,174 @@ + // WittyDemo2.ino 190419 4434b 112v !! 2 copies ajouté effet lum +// welcome with Rainbow and fast blink push n times +// 1 push red several move on-off and back to menu +// 2 pushes green same with pfm speed changes +// 3 control blue with most TV IR 1pulse stop, 2,3,4,5 move +// 4 demonstrate log dim +// 5 compte +// 6 test accelero Gy521 reset to restart demo + + #include "Witty.h" + #include "GetPush.h" +#define Npix 8 // nombre de LEDs +#define Brt 2 // max 31 brigtness +#include "Apa102.h" + #include "Telec.h" + #include "Pfm.h" + #include "Inter2.h" + #include "TerSer.h" + #define aadd 0x68*2 // a revoir + #include "I2Ctwi.h" + #include "Gy521.h" +void setup() { + SetupWitty(); + SetupApa102(); +// ApaClear (); // not required? + SetupInter2(); + SetupTerSer(); + SetupI2Ctwi(); + SetupGy521(); + Cli(2); DelMs(500); +} + +// Une fonction démo à mettre dans un .h sépare avec par exemple un générateur de caractères +// On veut tester un compteur binaire 1 allumé 0 sombre +void ShowByte (uint8_t nn,uint8_t rr,uint8_t gg,uint8_t bb) { + ApaHead(); + for (byte i=0; i=0; pfmR--) {pfmL=pfmR; ApaLogBlue(pfmR/5);Dac;} + pfmL=0; pfmR=0; ApaLogWhite(5); D; + for (pfmR=0; pfmR>-MaxVit; pfmR--) {pfmL=pfmR; ApaLogBlue(-pfmR/5);Dac;} + for (pfmR=-MaxVit; pfmR<0; pfmR++) {pfmL=pfmR; ApaLogGreen(-pfmR/5);Dac;} + pfmL=0; pfmR=0; ApaLogWhite(5); D; + DelMs(1000); + cli(); + break; + case 3: // Demo IRM control + ApaLogWhite(10); + byte nPress; + while(1) { + nPress= Compte(); + switch (nPress) { + case 1: // stop + ApaLogGreen(5); + FreeG; FreeD; break; + case 2: // avance + ApaLogRed(5); + AvG; AvD; break; + case 3: // tourneG + ApaLogBlue(5); + FreeG; AvD; break; + case 4: // tourneG + ApaLogPink(5); + AvG; FreeD; break; + case 5: // recule + ApaLogYellow(10); + RecG; RecD; break; + default: // plus de 5 + ShowByte (0x55,5,5,5); + FreeG; FreeD; break; + } // end switch + } // end while + case 5: // RGB // new numbering + sei(); + for (byte i=0;i<16;i++) {ApaLogRed(i); DelMs(100);} + for (byte i=16;i>0;i--) {ApaLogRed(i-1); DelMs(100);} + ApaLogGreen(1);DelMs(1000);ApaLogBlue(1);DelMs(1000);ApaLogRed(1);DelMs(1000); + ApaLogGreen(15);DelMs(1000);ApaLogBlue(15);DelMs(1000);ApaLogRed(15);DelMs(1000); // max intensity + // add your own tricks + cli(); + break; + case 6: + while(1) { + ShowByte (cnt5++,41,41,0); + DelMs(200); + } + // reset to quit + + case 4: // Demo6 Gy521 color effect click on terminal before to sse data + ApaLogYellow(10); + Text("EnvoiSer Gy521"); CR(); + while(1){ + ReadGy521(); + Text("AcX"); Dec16s(AcX); Text("GyX"); Dec16s(GyX); + Text("AcY"); Dec16s(AcY); Text("GyY"); Dec16s(GyY); + Text("AcZ"); Dec16s(AcZ); Text("GyZ"); Dec16s(GyZ); + CR(); + if (AcY> 10000) {ApaLogCyan(10);} + else if (AcY<-10000) {ApaLogBlue(10);} + if (AcZ>10000) {ApaLogRed(10);} + else if (AcZ<-10000) {ApaLogGreen(10);} + DelMs (200); + } + // reset to quit + default: // blink wait return ; + break; + } // end switch + +} // end loop + diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..b7ec737 --- /dev/null +++ b/keywords.txt @@ -0,0 +1,110 @@ +####################################### +# Syntax Coloring Map +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +TerSer KEYWORD1 +moz KEYWORD1 +uni KEYWORD1 +diz KEYWORD1 +cen KEYWORD1 +mil KEYWORD1 +dim KEYWORD1 +Normal KEYWORD1 +Spaces KEYWORD1 +Zeros KEYWORD1 +Compact KEYWORD1 +zr KEYWORD1 +zg KEYWORD1 +zb KEYWORD1 +status KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +Af3Dig KEYWORD2 +Af5Dig KEYWORD2 +ApaClear KEYWORD2 +ApaHead KEYWORD2 +ApaHtoRGB KEYWORD2 +ApaHue KEYWORD2 +ApaLed KEYWORD2 +ApaLogBlue KEYWORD2 +ApaLogCyan KEYWORD2 +ApaLogGreen KEYWORD2 +ApaLogPink KEYWORD2 +ApaLogRed KEYWORD2 +ApaLogRGB KEYWORD2 +ApaLogWhite KEYWORD2 +ApaLogYellow KEYWORD2 +ApaRainbow KEYWORD2 +ApaRGB KEYWORD2 +ApaS8 KEYWORD2 +ApaTail KEYWORD2 +Bin16 KEYWORD2 +Bin8 KEYWORD2 +BinDec16 KEYWORD2 +BinDec8 KEYWORD2 +BinDec9999 KEYWORD2 +Car KEYWORD2 +Clibyte KEYWORD2 +CliErr KEYWORD2 +Clignobyte KEYWORD2 +Compte KEYWORD2 +cntPush KEYWORD2 +CR KEYWORD2 +Dec16s KEYWORD2 +Dec16u KEYWORD2 +Dec8s KEYWORD2 +Dec8u KEYWORD2 +delMs KEYWORD2 +DelMs KEYWORD2 +Delus KEYWORD2 +DoPfm KEYWORD2 +Get KEYWORD2 +GetPush KEYWORD2 +Hex16 KEYWORD2 +Hex32 KEYWORD2 +Hex8 KEYWORD2 +ReadByte KEYWORD2 +ReadByteAt KEYWORD2 +ReadGy521 KEYWORD2 +ReadWord KEYWORD2 +ReadWordAt KEYWORD2 +SetupApa102 KEYWORD2 +SetupGy521 KEYWORD2 +SetupI2Ctwi KEYWORD2 +SetupInter2 KEYWORD2 +SetupSerNum KEYWORD2 +SetupTerSer KEYWORD2 +SetupWitty KEYWORD2 +TerBin8 KEYWORD2 +TerBinDec8 KEYWORD2 +TerCar KEYWORD2 +TerConvNibble KEYWORD2 +TerCR KEYWORD2 +TerDec16 KEYWORD2 +TerDec16S KEYWORD2 +TerDec8 KEYWORD2 +TerDec8S KEYWORD2 +TerDec9999 KEYWORD2 +TerHex12 KEYWORD2 +TerHex16 KEYWORD2 +TerHex20 KEYWORD2 +TerHex32 KEYWORD2 +TerHex8 KEYWORD2 +TerTextconst KEYWORD2 +Textconst KEYWORD2 +Textlnconst KEYWORD2 +TtBin8 KEYWORD2 +TwReadAck KEYWORD2 +TwReadNack KEYWORD2 +TwReStart KEYWORD2 +TwStart KEYWORD2 +TwStop KEYWORD2 +TwWrite KEYWORD2 +WriteByteAtbyte KEYWORD2 +WriteBytebyte KEYWORD2 +WriteWordAtbyte KEYWORD2 diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..a318bfc --- /dev/null +++ b/library.properties @@ -0,0 +1,9 @@ +name=Witty Library +version=1.0.0 +author=Didel +maintainer=Boxtec +sentence=Witty +paragraph=Several support libraries for the Witty self-balancing 2WD bot from Didel.com. See the WittyQuickStartGuide.pdf in the docs folder. +category=Other +url=https://git.boxtec.ch/didel/Witty +architectures=* \ No newline at end of file diff --git a/src/Apa102.h b/src/Apa102.h new file mode 100644 index 0000000..b9e19b9 --- /dev/null +++ b/src/Apa102.h @@ -0,0 +1,130 @@ +// Apa102.h ref 190303ino Doc Apa.pdf +// #include "Apa102.h" SetupApa102(); dans PP +#define nop asm ("nop") +#define bApaCk 1 +#define bApaDa 0 +#define ApaCkOn bitSet (PORTB,bApaCk) +#define ApaCkOff bitClear (PORTB,bApaCk) +#define ApaDaOn bitSet (PORTB,bApaDa) +#define ApaDaOff bitClear (PORTB,bApaDa) +#define ApaCkPulse bitSet(PORTB,bApaCk); bitClear(PORTB,bApaCk) + +void SetupApa102() { + DDRB |= (1< rend nbre d'actions 1 2 3.. + enum { WaitFirst, Pushing, NotPushing } npl= WaitFirst; +byte GetPush() { + cntPush=0; cntOff = 0; + while (cntOff < (500/5)) { // attend dernier push 0.5s + switch (npl) { + case WaitFirst: // on clignote en attendant un push + if (!PushOn) { + LedOff; DelMs (2); + if (cli++ == 40) { cli = 0; LedOn; DelMs (5);} + LedOff; break; + } + npl= Pushing; break; + case Pushing: // on attend le relâchemnent + LedOn; + if (PushOn) { break; } //attend relaché + LedOff; + cntPush++ ; cntOff= 0 ; + npl = NotPushing ; break ; + case NotPushing: // on attend un peu s'il y a une pression suivant + DelMs (5); + cntOff++; //200x5 = 1 sec + if (!PushOn) break ; //on relâche + npl = Pushing ; + break; + } // end switch + } // end while + npl = WaitFirst; // prépare appel suivant + // clignote cntPous fois + for (cli=0; cli // pas nécessaire? +// aadd defini dans pp avec #define aadd valeur adresse 8 bits sélect +// ? changera avec paramètre explicite? ou nom G521Twi +byte status; +void SetupI2Ctwi() { + TWSR = 1; //0 400kHz 1-160k 2 40k + TWBR = 0x0C; // bitrate + TWCR = (1 << TWEN); // autres bits à 0 +} + +void TwStart () { + TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // start + while (!(TWCR & (1 << TWINT))) {} +} +void TwReStart () { + TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // start + while (!(TWCR & (1 << TWINT))) {} +} +void TwStop () { + TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); // stop + for (volatile int i = 0; i < 20; i++) ; +} +void TwWrite (byte ab) { // addr8 ou data8 + TWDR = ab; + TWCR = (1 << TWINT) | (1 << TWEN); + while (!(TWCR & (1 << TWINT))) {} + ; status = TWSR & 0xF8; +} +byte TwReadAck () { + TWCR = (1 << TWINT) | (1 << TWEN) |(1<>8); TwWrite(dd&0xFF); TwStop(); +} +byte ReadByte() { + byte dd; + TwStart(); TwWrite(aadd+1); dd=TwReadNack(); TwStop(); + return (dd); +} +byte ReadWord() { + byte dd; + TwStart(); TwWrite(aadd+1); dd=(TwReadAck()<<8); dd|= TwReadNack(); TwStop(); + return (dd); +} +uint8_t ReadByteAt(byte rr) { + byte dd; + TwStart(); TwWrite(aadd); TwWrite(rr); + TwReStart(); TwWrite(aadd+1); dd=TwReadNack(); TwStop(); + return(dd); +} +uint16_t ReadWordAt(byte rr) { + uint16_t dd; + TwStart(); TwWrite(aadd); TwWrite(rr); + TwReStart(); TwWrite(aadd+1); dd=(TwReadAck()<<8); dd |=(TwReadNack()); TwStop(); + return(dd); +} + + + diff --git a/src/Inter2.h b/src/Inter2.h new file mode 100644 index 0000000..929ce2a --- /dev/null +++ b/src/Inter2.h @@ -0,0 +1,20 @@ +//Inter2.h +//Dans PP #include "Inter2.h" SetupInter2(); +volatile byte cpf,cup,cdo; +ISR (TIMER2_OVF_vect) { +// TCNT2 = 256-20; // 2M 20 11us 100 35us 200 85us + TCNT2 = 141; // 58 us calibre pour Tell + cup++;cdo++; + if (cpf++ > 35) { cpf=0; // toutes les 35x58= 2ms + DoPfm (); //durée 2us + } +} + +void SetupInter2() { // initialisation + TCCR2A = 0; //default + TCCR2B = 0b00000010; // 2MHz + TIMSK2 = 0b00000001; // TOIE2 + //TIFR2 flag TOV2 + sei(); +} + diff --git a/src/Pfm.h b/src/Pfm.h new file mode 100644 index 0000000..29205e0 --- /dev/null +++ b/src/Pfm.h @@ -0,0 +1,39 @@ +//Pfm.h avec table vit +//#include "Pfm.h" SetupPfm(); dans le pp +volatile int8_t pfmL, pfmR; // -80 .. +80 +#define MaxPfm 80 +volatile byte pfmCntL; +volatile byte pfmCntR; +void DoPfm () { + char tempL,tempR; + if (pfmR > MaxPfm) pfmR=MaxPfm; // saturer + if (pfmR < -MaxPfm) pfmR= -MaxPfm; + + if (pfmR >=0) { + if ((pfmCntR += pfmR) > MaxPfm) { + pfmCntR -= MaxPfm; AvD; } + else { FreeD; } + } + if (pfmR <0) { + tempR= -pfmR; // ou pfR= ABS(pfR) + if ((pfmCntR += tempR) > MaxPfm) { + pfmCntR -= MaxPfm; RecD; } + else { FreeD; } + } + if (pfmL > MaxPfm) pfmL=MaxPfm; // saturer + if (pfmL < -MaxPfm) pfmL= -MaxPfm; + + if (pfmL >=0) { + if ((pfmCntL += pfmL) > MaxPfm) { + pfmCntL -= MaxPfm; AvG; } + else { FreeG; } + } + if (pfmL <0) { + tempL= -pfmL; // ou pfL= ABS(pfL) + if ((pfmCntL += tempL) > MaxPfm) { + pfmCntL -= MaxPfm; RecG; } + else { FreeG; } + } +} + + diff --git a/src/SerNum.h b/src/SerNum.h new file mode 100644 index 0000000..ce1ccb1 --- /dev/null +++ b/src/SerNum.h @@ -0,0 +1,158 @@ +// SerNum.h Formats avec zéros enlever +//Dans PP #include "SerNum.h" SetupSerNum(); +void SetupSerNum() { + UBRR0=F_CPU/(9600*16L)-1; // set speed + UCSR0B=0x18; // -- -- -- rxe txe -- -- -- + UCSR0C=0x06; // set mode: 8 data bits, no parity, 1 stop bit +} +//Rx S1 est toujours en sortie +//Tx S2 aussi, sous controle du 328 si TerOn (S2 ignoré); +#define TerOn UBRR0=F_CPU/(9600*16L)-1; UCSR0C=0x06; UCSR0B=0x08 +#define TerOff DelMs(3); UCSR0C=0x06; UCSR0B=0 + +void TerCar( byte dd) { // write bloquant Ok initial + while(!(UCSR0A&0x20));// wait + UDR0=dd; // OK, send it now! +} +void TerCR() { + TerCar(13);TerCar(10); +} +void TerText(const char str[]) { + for (byte i=0; i< strlen(str); i++) { + TerCar(str[i]); + } +} + + +void TerBin8 (byte bb) { + for (byte i=0;i<8;i++) { + if (bb&0x80) TerCar('1'); + else TerCar('0'); + bb <<= 1; + } + TerCar(' '); +} +char TerConvNibble (byte nn) { // converti 4 bit hexa en Ascii + byte cc; + if (nn<10) {cc = nn + '0';} + else {cc = nn-10 + 'A';} + return cc; +} +void TerHex8 (byte hh) { + byte cc; + cc = TerConvNibble (hh >> 4) ; // ne modifie pas hh + TerCar(cc); + cc = TerConvNibble (hh & 0x0F) ; + TerCar(cc); + TerCar(' '); // space +} +void TerHex16 (uint16_t hh) { + byte cc; + cc = TerConvNibble (hh >> 12) ; TerCar(cc); + cc = TerConvNibble ((hh >> 8)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 4)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh )&0x0F) ; TerCar(cc); + TerCar(' '); +} +void TerHex12 (uint16_t hh) { + byte cc=0; + cc = TerConvNibble ((hh >> 8)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 4)&0x0F) ; TerCar(cc); + cc = TerConvNibble (hh & 0x0F) ; TerCar(cc); + TerCar(' '); +} +void TerHex20 (uint32_t hh) { + byte cc; + cc = TerConvNibble ((hh >> 16)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 12)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 8 )&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 4 )&0x0F) ; TerCar(cc); + cc = TerConvNibble (hh & 0x0F) ; TerCar(cc); + TerCar(' '); +} +void TerHex32 (uint32_t hh) { + byte cc; + + cc = TerConvNibble ((hh >> 28)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 24)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 20)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 16)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 12)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 8)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh >> 4)&0x0F) ; TerCar(cc); + cc = TerConvNibble ((hh )&0x0F) ; TerCar(cc); + TerCar(' '); +} +uint16_t TerBinDec8 (uint8_t bb) { + uint16_t dd=0; + for (byte i=0; i<8; i++) { + if ((dd & 0x0F)>0x04) {dd += 0x03;} + if ((dd & 0xF0)>0x40) {dd += 0x30;} + dd=dd<<1; + if ((bb & 0x80)) {dd += 1;} //inject bit + bb=bb<<1; // prepare next bit + } + return dd; +} +/*#define TerDec8(v) \ + do { const int8_t vv = (v); \ + if(vv<0) { TerDec8S(vv); } \ + else { TerDec8U(vv); } \ + } while(0) +*/ +void TerDec8 (uint8_t hh) { + TerHex12(TerBinDec8(hh)); +} + +void TerDec8S (int8_t hh) { + if (hh<0) { // négatif + TerCar('-'); hh = -hh; + } else { + TerCar('+'); + } + TerHex12(TerBinDec8(hh)); +} +uint16_t BinDec9999 (uint16_t bb) { //0x270F max + uint32_t dd=0; + for (byte i=0; i<16; i++) { + if ((dd & 0x000F)>0x0004) {dd += 0x0003;} + if ((dd & 0x00F0)>0x0040) {dd += 0x0030;} + if ((dd & 0x0F00)>0x0400) {dd += 0x0300;} + if ((dd & 0xF000)>0x4000) {dd += 0x3000;} + dd=dd<<1; + if ((bb & 0x8000)) {dd += 1; } //inject bit + bb<<=1; // prepare next bit + } + return dd; +} + +uint32_t BinDec16 (uint16_t bb) { + uint32_t dd=0; + for (byte i=0; i<16 ; i++) { + if ((dd & 0x000F)>0x0004) {dd += 0x0003;} + if ((dd & 0x00F0)>0x0040) {dd += 0x0030;} + if ((dd & 0x0F00)>0x0400) {dd += 0x0300;} + if ((dd & 0xF000)>0x4000) {dd += 0x3000;} + dd=dd<<1; + if ((bb & 0x8000)) {dd += 1; } //inject bit + bb<<=1; // prepare next bit + } + return dd; +} +void TerDec9999 (uint16_t hh) { // limité à 0x2703 + if (hh>9999) { TerText("over "); } + else TerHex16(BinDec9999(hh)); +} +void TerDec16 (uint32_t hh) { // + TerHex20(BinDec16(hh)); +} + +void TerDec16S (int16_t hh) { // signé + if (hh<0) { // negatif + TerCar('-'); hh = -hh; + } else { + TerCar('+'); + } + TerHex20(BinDec16(hh)); +} + diff --git a/src/Telec.h b/src/Telec.h new file mode 100644 index 0000000..a2a6c58 --- /dev/null +++ b/src/Telec.h @@ -0,0 +1,17 @@ +//Telec.h Telec simple +// #include "Telec.h" setup dans Witty.h + +// Compte rend le nombre de pressions courtes +#define DelSil 100 +#define DelCnt 500 +byte Compte () { + byte cnt; + while (!IrmOn) ; // attend 1ere imp + int cDel=0; cnt=0; + while (cDel++ SetupTerSer(); +void SetupTerSer() { + UBRR0= 103; // 9600 + UCSR0B=0x18; // -- -- -- rxe txe -- -- -- + UCSR0C=0x06; // set mode: 8 data bits, no parity, 1 stop bit +} + +uint8_t moz=0; // Default value +#define Normal moz=0 +#define Spaces moz=1 +#define Zeros moz=2 +#define Compact moz=3 + +uint8_t Get() { // read blocking + while (!(UCSR0A&0x80)); // wait + return UDR0; +} + +void Car( uint8_t dd) { // write blocking + while(!(UCSR0A&0x20));// wait + UDR0=dd; // OK, send it now! +} + +void CR() { + Car(13);Car(10); // CR LF +} + +void Text(const char str[]) { + for (uint8_t i=0; i< strlen(str); i++) { Car(str[i]); } +} + +void Textln(const char str[]) { + for (uint8_t i=0; i< strlen(str); i++) { Car(str[i]); } + Car(13);Car(10); +} + +void TtBin8 (uint8_t bb) { // auxiliary function + for (uint8_t i=0;i<8;i++) { + if (bb&0x80) Car('1'); + else Car('0'); + bb <<= 1; + } +} +void Bin8 (uint8_t bb) { + TtBin8 (bb); Car(' '); +} +void Bin16 (uint16_t bb) { + TtBin8 (bb>>8); Car('.'); + TtBin8 (bb&0xFF); + Car(' '); +} + +char ConvNibble (uint8_t nn) { // 4 bit binary to Ascii + uint8_t cc; + if (nn<10) {cc = nn + '0';} + else {cc = nn-10 + 'A';} + return cc; +} + +void Hex8 (uint8_t hh) { + uint8_t cc; + cc = ConvNibble (hh >> 4); Car(cc); + cc = ConvNibble (hh & 0x0F) ; Car(cc); + Car(' '); // space +} +void Hex16 (uint16_t hh) { + uint8_t cc; + cc = ConvNibble (hh >> 12) ; Car(cc); + cc = ConvNibble ((hh >> 8)&0x0F) ; Car(cc); + cc=hh&0xFF; Hex8 (cc); + Car(' '); +} +void Hex32 (uint32_t hh) { + uint8_t cc; + cc = ConvNibble (hh >> 28) ; Car(cc); + cc = ConvNibble ((hh >> 24)&0x0F) ; Car(cc); + cc = ConvNibble ((hh >> 20)&0x0F) ; Car(cc); + cc = ConvNibble ((hh >> 16)&0x0F) ; Car(cc); + cc=hh&0xFFFF; Hex16 (cc); + Car(' '); +} + +// -- new Decimal functions with 4 modes (see above) + +uint8_t uni,diz,cen,mil,dim; +uint8_t tyn; // type number +uint8_t sig; + +void BinDec8 (uint8_t bb) { + uni=0;diz=0;cen=0; + tyn=0; if (bb==0) return; + uni=bb%10; bb=bb/10; if (bb==0){tyn=1;return;} + diz=bb%10; bb=bb/10; if (bb==0){tyn=2;return;} + cen=bb; tyn=3; +} + +void Af3Dig() { + switch (moz) { + case 0: // Normal signe devant le nombre + switch (tyn) { + case 0: + Car(' '); Car(' ');Car(' ');Car('0'); Car(' '); break; + case 1: + Car(' ');Car(' '); Car(sig); Car(uni+'0'); Car(' '); break; + case 2: + Car(' '); Car(sig); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 3: + Car(sig); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + } // end switch tyn + break; // end case moz 0 + case 1: // Spaces + switch (tyn) { + case 0: + Car(' '); Car(' ');Car(' ');Car('0'); Car(' '); break; + case 1: + Car(sig);Car(' '); Car(' '); Car(uni+'0'); Car(' '); break; + case 2: + Car(sig); Car(' '); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 3: + Car(sig); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + } // end switch tyn + break; // end case moz 1 + case 2: // Zeros + switch (tyn) { + case 0: + Car(' '); Car('0');Car('0');Car('0'); Car(' '); break; + case 1: + Car(sig);Car('0'); Car('0'); Car(uni+'0'); Car(' '); break; + case 2: + Car(sig); Car('0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 3: + Car(sig); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + } // end switch tyn + break; // end case moz 2 + case 3: // Compact + switch (tyn) { + case 0: + Car('0'); Car(' '); break; + case 1: + Car(sig); Car(uni+'0'); Car(' '); break; + case 2: + Car(sig); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 3: + Car(sig); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + } // end switch tyn + break; // endcase moz 3 + } // end switch moz +} +// this macro generate a warning depending on sign +#define Dec8(v) \ + do { typeof(v) _v = -1; \ + if (_v < 0) { Dec8s(v); } \ + else { Dec8u(v); } \ + } while(0); + +void Dec8u (uint8_t hh) { + sig=' '; + BinDec8 (hh); Af3Dig(); +} + +void Dec8s (int8_t hh) { + if (hh<0) { // négatif + sig='-'; hh = -hh; + } else { + sig='+'; + } + BinDec8 (hh); Af3Dig(); +} + +//----------------- +void BinDec16 (uint32_t bb) { + uni=0;diz=0;cen=0;mil=0;dim=0; + tyn=0; if (bb==0) return; + uni=bb%10; bb=bb/10; if (bb==0){tyn=1;return;} + diz=bb%10; bb=bb/10; if (bb==0){tyn=2;return;} + cen=bb%10; bb=bb/10; if (bb==0){tyn=3;return;} + mil=bb%10; bb=bb/10; if (bb==0){tyn=4;return;} + dim=bb; tyn=5; +} + +void Af5Dig() { + switch (moz) { + case 0: // Normal mode + switch (tyn) { + case 0: + Car(' '); Car(' '); Car(' ');Car(' ');Car(' ');Car('0'); Car(' '); break; + case 1: + Car(' '); Car(' '); Car(' ');Car(' ');Car(sig);Car(uni+'0'); Car(' '); break; + case 2: + Car(' '); Car(' '); Car(' ');Car(sig);Car(diz+'0');Car(uni+'0'); Car(' '); break; + case 3: + Car(' '); Car(' '); Car(sig);Car(cen+'0');Car(diz+'0');Car(uni+'0'); Car(' '); break; + case 4: + Car(' '); Car(sig); Car(mil+'0');Car(cen+'0');Car(diz+'0');Car(uni+'0'); Car(' '); break; + case 5: + Car(sig); Car(dim+'0'); Car(mil+'0');Car(cen+'0');Car(diz+'0');Car(uni+'0'); Car(' '); break; + } // end switch tyn + break; + case 1: // Spaces + switch (tyn) { + case 0: + Car(' '); Car(' ');Car(' ');Car(' ');Car(' ');Car('0'); Car(' '); break; + case 1: + Car(sig);Car(' '); Car(' ');Car(' ');Car(' '); Car(uni+'0'); Car(' '); break; + case 2: + Car(sig); Car(' '); Car(' ');Car(' ');Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 3: + Car(sig); Car(' '); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 4: + Car(sig); Car(' ');Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 5: + Car(sig); Car(dim+'0');Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + } // end switch tyn + break; // case 1 + case 2: // Zeros + switch (tyn) { + case 0: + Car(' '); Car('0');Car('0');Car('0');Car('0');Car('0'); Car(' '); break; + case 1: + Car(sig); Car('0');Car('0');Car('0'); Car('0'); Car(uni+'0'); Car(' '); break; + case 2: + Car(sig); Car('0');Car('0');Car('0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 3: + Car(sig); Car('0');Car('0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 4: + Car(sig); Car('0');Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 5: + Car(sig); Car(dim+'0');Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + } // end switch tyn + break; + case 3: // Compact + switch (tyn) { + case 0: + Car('0'); Car(' '); break; + case 1: + Car(sig); Car(uni+'0'); Car(' '); break; + case 2: + Car(sig); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 3: + Car(sig); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 4: + Car(sig); Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + case 5: + Car(sig); Car(dim+'0');Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break; + } // end switch tyn + break; + } // end switch moz +} + +// this macro generate a warning depending on sign +#define Dec16(v) \ + do { typeof(v) _v = -1; \ + if (_v < 0) { Dec16s(v); } \ + else { Dec16u(v); } \ + } while(0); + +void Dec16u (uint16_t hh) { + sig=' '; + BinDec16(hh); Af5Dig(); +} + +void Dec16s (int16_t hh) { + if (hh<0) { // négatif + sig='-'; hh = -hh; + } else { + sig='+'; + } + BinDec16(hh); Af5Dig(); +} +// end code + + diff --git a/src/Witty.h b/src/Witty.h new file mode 100644 index 0000000..12d59cf --- /dev/null +++ b/src/Witty.h @@ -0,0 +1,74 @@ +//Witty.h 190124 voir www.didel.com/Witty.pdf +//Dans PP #include "Witty.h" SetupWitty(); +//Strip RGB - voir Apa102.h et www.didel.com/ApaWitty.pdf +//Gy521 - voir Gy521.h www.didel.com/Gy521Witty.pdf +//Simple teled control +//Push et Led - voir GetPush.h et https://www.didel.com/diduino/Poussoir.pdf +#define bLed 1 // PORTC +#define bPush 0 // actif à zero +#define PushOn (!(PINC&(1<