Fórum témák

» Több friss téma
Fórum » Arduino
A klónok CH340 Soros-USB illesztőjének drivere (Letöltés)
Lapozás: OK   285 / 864
(#) Kovidivi válasza atus1981 hozzászólására (») Okt 29, 2016 / 1
 
A setup ugyanolyan kód, mint a loop. Annyiban különbözik, hogy csak egyszer fut le reset vagy táp megjelenése után.
(#) vyky hozzászólása Okt 30, 2016 /
 
Szia Kovidivi. A helyzet az,hogy "szépen" gyorsul a motor és lassul,de gyorsításkor éppen csak megy ahogy illik,és (gondolom) amikor eléri a motor a valós feszültséget,hirtelen begyorsul.Nem tudom,érthető-e a gondom.Szóval azt meg lehetne oldani,hogy nem rántson a motor amikor teljes sebességre vált? Köszönöm előre is.
(#) david10 hozzászólása Okt 30, 2016 /
 
Sziasztok, volna egy rövid kérdésem:
Adott az SD Locker 2 forráskódja, amit Atmega328-ra írtak, amit én átszeretnék írni az Arduino nyelvére és kiszeretném bőviteni néhány aprósággal. Valósziű, hogy cikk is lesz belőle.
Az "átírom az Arduino nyelvére " alatt azt értem, hogy a bit müveleteket kicserélem pinMode, digitalWrite stb. -re.
A kérdésem:
Azt értem, hogy az SPI_DDR-el kiválaszthatom, hogy ki/be menet legyen az adott port,de az SPI_PORT mire szolgál? High-ra teszen bizonyos portokat? Ha igen, akkor miért a be/ki menet választás előtt van?
  1. SPI_PORT = SPI_PORT | ((1<<MOSI_BIT) | (1<<SCK_BIT));   // drive outputs to the SPI port
  2. SPI_DDR = SPI_DDR | ((1<<MOSI_BIT) | (1<<SCK_BIT));             // make the proper lines outputs

Csatoltam az eredeti forráskódot .c és .txt formátumban. A két fájl tartalma természetesen azonos.
A választ előre is köszönöm!
A hozzászólás módosítva: Okt 30, 2016
(#) kapu48 válasza david10 hozzászólására (») Okt 30, 2016 1 /
 
Arduino-nál nem kell ezzel foglalkoznod!

A : Bővebben: SPI.begin
Mindent beállít helyetted!
A hozzászólás módosítva: Okt 30, 2016
(#) david10 válasza kapu48 hozzászólására (») Okt 30, 2016 /
 
Köszönöm a válaszod!
A számomra felfoghatatlan bonyolultságú részet kitörültem, betettem helyette az SPI.begin-t és minden müködik mint előtte!
Mégegyszer köszönöm szépen a válaszod!
(#) szikorapéter válasza szikorapéter hozzászólására (») Okt 30, 2016 /
 
Esetleg valaki választ a kérdésemre? Direkt ide tettem fel mert az eprom írós topicba nem való (arduino alapú).
(#) kapu48 válasza szikorapéter hozzászólására (») Okt 30, 2016 1 /
 
A HW. valószínüleg tudja!

De mivel minden EEPROM lábkiosztása, időzítése, programozó feszültsége különböző!

Ezért a vezérlő programnak is tudnia kel! + a felhasználónak is, hogy mit hova kössön.
(#) szikorapéter válasza kapu48 hozzászólására (») Okt 30, 2016 /
 
Egyszerű ablakos epromot akarok vele programozni azért is a kérdés,mivel annak programozói feszültsége magasabb. Kár hogy nincs ehhez a project-hez magyar leírás.
(#) kapu48 válasza szikorapéter hozzászólására (») Okt 30, 2016 1 /
 
Mit jelent, hogy egyszerű?
Sajnos ezek nem egyformák!

Minden EEPROM tipusnak van adatlapja.
Az abban előírt paramétereket kel megvalósítani, és betartani!
A hozzászólás módosítva: Okt 30, 2016
(#) szikorapéter válasza kapu48 hozzászólására (») Okt 30, 2016 /
 
Értem,akkor egyenlőre lehet összerakom ezt és rendelek hozzá egy 5V-os írófeszültségű eepromot és megpróbálom.
(#) GPeti1977 hozzászólása Okt 30, 2016 /
 
Karácsonyra készítenék egy kis LED-es fényjátékot. Vettem 2x5m LED szalagot WS2812 egyenként címezhető RGB LED-del, abból építettem egy 72x8 pixeles táblát, a fényeket SD kártyáról vannak kiolvasva amit .bmp 24 bites fájlba kell megrajzolni pl pain-ben, működik is de csak arduino nano-val azaz ATMEGA328 procival, mint látjátok a csatolt programban csak 128 LED-et tudok használni mert elfogyott a RAM, nekem 576x(3) LED kellene, ahhoz ott van az Arduino Mega de azzal nem működik, a FAB_LED.h használom, de ott van ami asm-ben van megírva így nem tudom átírni -nincs meg a tudásom- a kódot hogy ATMEGA2560 is működjön, ugyanis ha abba írom bele a programot akkor a kimeneten nem jön ki jel. a segítséget kérném valakitől hogy mit kellene módosítani.

  1. /// The LED strip DI (data input) line should be on port D6 (Digital pin 6 on
  2. /// Arduino Uno). If you need to change the port, change  declarations below
  3. /// , for example  "ws2812b<D,6> myWs2812" to "ws2812b<B,4> myWs2812"
  4. /// if you wanted to use port B4.
  5. #include "FAB_LED.h"
  6. #include <SPI.h>
  7. #include <SD.h>
  8. const int effect = 10;
  9. const int chipSelect = 10;
  10. //uint8_t pos;
  11. unsigned int pos;
  12. unsigned int posf;
  13. unsigned int i;
  14. /// @brief This parameter says how many LEDs will be lit up in your strip.
  15. //const uint8_t numPixels = 255;
  16. const int numPixels = 128;
  17. /// @brief This says how bright LEDs will be (max is 255)
  18. const uint8_t maxBrightness = 255;
  19. char* playfile;
  20. /// @brief Declare the protocol for your LED strip. Data is wired to port D6,
  21. /// and the clock to port D5, for APA102 only.
  22. //ws2812b<D,6>  LEDstrip;
  23. ws2812<D,6>  LEDstrip;
  24. //sk6812<D,6>   LEDstrip;
  25. //sk6812b<D,6>  LEDstrip;
  26. //apa104<D,6>   LEDstrip;
  27. //apa106<D,6>   LEDstrip;
  28. //apa102<D,6,D,5>  LEDstrip;
  29.  
  30. /// @brief Array holding the pixel data.
  31. /// Note you have multiple formats available, to support any LED type. If you
  32. /// use the wrong type, FAB_LED will do the conversion transparently for you.
  33. hbgr  pixels[numPixels] = {};
  34. //grb  pixels[numPixels] = {};
  35. //grbw  pixels[numPixels] = {}
  36. int n = 0;
  37.  
  38. void setup()
  39. {
  40.   Serial.begin(115200);
  41.   Serial.print("Initializing SD card...");
  42.  
  43.   // see if the card is present and can be initialized:
  44.   if (!SD.begin(chipSelect)) {
  45.     Serial.println("Card failed, or not present");
  46.     // don't do anything more:
  47.     return;
  48.   }
  49.   Serial.println("card initialized.");
  50.    //pinMode(6, OUTPUT);
  51.   // RGB initializes to zero, but for APA102, h is set to full brightness.
  52.   // Depending on which class you use for your pixels, comment the h or w field
  53.   // accordingly.
  54.   for (pos = 0; pos < numPixels; pos++) {
  55.     pixels[pos].h = 0xFF; // hgrb has h field
  56.     pixels[pos].g = 0;
  57.     pixels[pos].b = 0;
  58.     pixels[pos].r = 0;
  59.     //pixels[pos].w = 0; // grbw has w field
  60.   }
  61.  
  62.   LEDstrip.refresh(); // Hack: needed for apa102 to display last pixels
  63.  
  64.   // Clear display
  65.   LEDstrip.sendPixels(numPixels,pixels);
  66.   LEDstrip.refresh(); // Hack: needed for apa102 to display last pixels
  67. }
  68.  
  69.  
  70. void loop()
  71. {
  72.   int m = 0;
  73.   switch(n) {
  74.     case 0:
  75.     playfile = "001.bmp";
  76.     break;
  77.     case 1:
  78.     playfile = "002.bmp";
  79.     break;
  80.     case 2:
  81.     playfile = "003.bmp";
  82.     break;
  83.     case 3:
  84.     playfile = "004.bmp";
  85.     break;
  86.     case 4:
  87.     playfile = "005.bmp";
  88.     break;
  89.     case 5:
  90.     playfile = "006.bmp";
  91.     break;
  92.     case 6:
  93.     playfile = "007.bmp";
  94.     break;
  95.     case 7:
  96.     playfile = "008.bmp";
  97.     break;
  98.     case 8:
  99.     playfile = "009.bmp";
  100.     break;
  101.     case 9:
  102.     playfile = "010.bmp";
  103.     break;
  104.     case 10:
  105.     playfile = "011.bmp";
  106.     break;
  107.     case 11:
  108.     playfile = "012.bmp";
  109.     break;
  110.     case 12:
  111.     playfile = "013.bmp";
  112.     break;
  113.     case 13:
  114.     playfile = "014.bmp";
  115.     break;
  116.     case 14:
  117.     playfile = "015.bmp";
  118.     break;
  119.     case 15:
  120.     playfile = "016.bmp";
  121.     break;
  122.     case 16:
  123.     playfile = "017.bmp";
  124.     break;
  125.     case 17:
  126.     playfile = "018.bmp";
  127.     break;
  128.     case 18:
  129.     playfile = "019.bmp";
  130.     break;
  131.     case 19:
  132.     playfile = "020.bmp";
  133.     break;
  134.    
  135.  
  136.     default:
  137.     playfile = "001.bmp";
  138.   }
  139.  
  140.   File dataFile = SD.open(playfile);
  141.  
  142.   if (dataFile) {
  143.     long start1 = millis();
  144.     while (dataFile.available()) {
  145.       if(m<1) {
  146.       for (i = 0; i <  54 ; i++) {
  147.         dataFile.read();
  148.         m++;
  149.       }
  150.       }
  151.        
  152.        for (pos = 0; pos <  numPixels ; pos++) {
  153.       byte b = dataFile.read();
  154.       pixels[pos].b = b;
  155.       //Serial.print(b);
  156.       //Serial.print(" ");
  157.       byte g = dataFile.read();
  158.       pixels[pos].g = g;
  159.       //Serial.print(g);
  160.       //Serial.print(" ");
  161.       byte r =  dataFile.read();
  162.       pixels[pos].r = r;
  163.       //Serial.println(r);
  164.      
  165.       //Serial.print(pos);
  166.       //Serial.print(" ");
  167.       //Serial.println();
  168.        }
  169.       //n++;
  170.      
  171.      
  172.       LEDstrip.sendPixels(numPixels, pixels);
  173.       LEDstrip.refresh();      
  174. //delay(10);
  175.        
  176.     }
  177.     dataFile.close();
  178.    
  179.     long stopp = millis();
  180.     long tim = stopp-start1;
  181.     Serial.println();
  182.     Serial.print(tim);
  183.     Serial.println("ms 128 LED");
  184.     //while(true) {}
  185.   }
  186.   // if the file isn't open, pop up an error:
  187.   else {
  188.     Serial.println("error opening datalog.bin");
  189.   }
  190. n++;
  191. if (n>(effect)) n = 0;
  192. Serial.print("N ");
  193. Serial.print(n);
  194. delay(100);
  195.  
  196. }
  197.  
  198.  
  199. A FAB_LED.h:
  200.  
  201. [code=c]
  202. ////////////////////////////////////////////////////////////////////////////////
  203. ////////////////////////////////////////////////////////////////////////////////
  204. // Fast Addressable LED Library
  205. // Copyright (c)2015 Dan Truong
  206. //
  207. // Licence: limited use is authorized for the purpose of beta testing
  208. //
  209. // The goal of this library is to be very fast, very sm and take advantage
  210. // of the relaxed LED timings to ow other work besides bit banging while the
  211. // LEDs are being updated.
  212. // The library ows cing multiple times the same function to repeat
  213. // patterns, and ows inline color palette management to save on memory space
  214. // usage. The palette conversion is done inline as the pixels are being painted.
  215. //
  216. // The bit-banging is being done using GCC built-ins to avoid contrived ASM
  217. // language code blocks support. It should work for any arduino platform of
  218. // 16MHz or more to function.
  219. ////////////////////////////////////////////////////////////////////////////////
  220. ////////////////////////////////////////////////////////////////////////////////
  221. #ifndef FAB_LED_H
  222. #define FAB_LED_H
  223.  
  224. #include <stdint.h>
  225. #include <Arduino.h>
  226.  
  227. // This code is sensitive to optimizations if you want to cascade function cs,
  228. // so make the IDE compile at -O2 instead of -Os (size).
  229. #pragma GCC optimize ("-O2")
  230.  
  231. // static_assert is a built-in C++ 11 assert that Arduino does not seem to support
  232. #ifndef static_assert
  233. #define STATIC_ASSERT4(COND,MSG,LIN) typedef char assert_##MSG##_##LIN[(!!(COND))*2-1]
  234. #define STATIC_ASSERT3(X,M,L) STATIC_ASSERT4(X, M, L)
  235. #define STATIC_ASSERT2(X,M,L) STATIC_ASSERT3(X,M,L)
  236. #define STATIC_ASSERT(X,M)    STATIC_ASSERT2(X,M,__LINE__)
  237. #else
  238. #define SA2TXT2(x) # x
  239. #define SA2TXT(x) SA2TXT2(x)
  240. #define STATIC_ASSERT(X,M) static_assert(X, SA2TXT(M))
  241. #endif
  242.  
  243. ////////////////////////////////////////////////////////////////////////////////
  244. /// @brief typed pixel structures for every LED protocol supported.
  245. /// These simplify access to a pixel byte array, or even to send typed pixels
  246. /// to the LED strip, as the programmer directly access pixel colors by name.
  247. ////////////////////////////////////////////////////////////////////////////////
  248.  
  249. // Pixel colors byte order, 0 and 7 invalid.
  250. #define PT_RGB   0b00100000
  251. #define PT_GRB   0b01000000
  252. #define PT_BGR   0b10000000
  253. //#define PT_RBG 0b11000000
  254. //#define PT_GBR 0b10100000
  255. //#define PT_BRG 0b01100000
  256. #define PT_COL   0b11100000 // Mask for 3-byte colors
  257. #define PT_IS_SAME_COLOR(v1, v2) ((v1) & T_COL == (v2) & T_COL)
  258.  
  259. // Extra pixels bytes, 0 none, 2 invalid.
  260. #define PT_XXXW  0b00000001 // Postfix white pixel brightness (sk6812)
  261. #define PT_BXXX  0b00000010 // APA 102 prefix brightness pixel 0b111bbbbb
  262. #define PT_XBYT  0b00000011 // Mask for extra byte(s)
  263. #define PT_HAS_WHITE(v)  ((v) & PT_XBYT == PT_XXXW)
  264. #define PT_HAS_BRIGHT(v) ((v) & PT_XBYT == PT_BXXX)
  265. #define PT_IS_3B(v) ((v) & PT_XVAL == 0)
  266. #define PT_IS_4B(v) ((v) & PT_XVAL != 0)
  267.  
  268. // apa102, apa106 native color order
  269. typedef struct {
  270.         static const uint8_t type = PT_RGB;
  271.          { uint8_t r; uint8_t red; };
  272.          { uint8_t g; uint8_t green; };
  273.          { uint8_t b; uint8_t blue; };
  274. } rgb;
  275.  
  276. // apa104, ws2812 native color order
  277. typedef struct {
  278.         static const uint8_t type = PT_GRB;
  279.          { uint8_t g; uint8_t green; };
  280.          { uint8_t r; uint8_t red; };
  281.          { uint8_t b; uint8_t blue; };
  282. } grb;
  283.  
  284. typedef struct {
  285.         static const uint8_t type = PT_BGR;
  286.          { uint8_t b; uint8_t blue; };
  287.          { uint8_t g; uint8_t green; };
  288.          { uint8_t r; uint8_t red; };
  289. } bgr;
  290.  
  291. // sk6812 native color order
  292. typedef struct {
  293.         static const uint8_t type = PT_RGB | PT_XXXW;
  294.          { uint8_t r; uint8_t red; };
  295.          { uint8_t g; uint8_t green; };
  296.          { uint8_t b; uint8_t blue; };
  297.          { uint8_t w; uint8_t white; };
  298. } rgbw;
  299.  
  300. // sk6812 native color order
  301. typedef struct {
  302.         static const uint8_t type = PT_GRB | PT_XXXW;
  303.          { uint8_t g; uint8_t green; };
  304.          { uint8_t r; uint8_t red; };
  305.          { uint8_t b; uint8_t blue; };
  306.          { uint8_t w; uint8_t white; };
  307. } grbw;
  308.  
  309. // apa102 native color order
  310. typedef struct {
  311.         static const uint8_t type = PT_BGR | PT_BXXX;
  312.          { uint8_t B; uint8_t brightness;
  313.                 uint8_t w; uint8_t white;
  314.                 uint8_t h; uint8_t header; };
  315.          { uint8_t b; uint8_t blue; };
  316.          { uint8_t g; uint8_t green; };
  317.          { uint8_t r; uint8_t red; };
  318. } hbgr;
  319.  
  320.  
  321. ////////////////////////////////////////////////////////////////////////////////
  322. /// @brief Helper macro for palette index encoding into a char * array when
  323. /// using an 8bit or less per pixel with a uint8_t type.
  324. ////////////////////////////////////////////////////////////////////////////////
  325.  
  326. /// @brief computes the size of a uint8_t array that uses pixels encoded with a
  327. /// palette. For example: uint8_t buffer[ARRAY_SIZE(128, 2)]; is an array of 128
  328. /// pixels encoded with 2 bits per pixel (4 colors).
  329. #define ARRAY_SIZE(numPixels, bitsPerPixel) (((numPixels)+7) / 8 * (bitsPerPixel))
  330.  
  331. /// @brief Encode a pixel's color
  332. /// For example, for encoding colors on 2 bits (4 colors, 0,1,2,3, in the palette),
  333. /// Encoding color #3, using 2 bits per pixels, in the buffer for pixel i:
  334. /// SET_PIXEL(buffer, i, 2, 3);
  335. #define SET_PIXEL(array, index, bitsPerPixel, color)                           \
  336.         _SET_PIXEL((array), (index), (bitsPerPixel), (color))
  337.  
  338. /// @brief extract a pixel's palette color index  a pixel array
  339. /// For example, colorIndex = GET_PIXEL(buffer, i, 2);
  340. #define GET_PIXEL(array, index, bitsPerPixel)                                  \
  341.         _GET_PIXEL((array), (index), (bitsPerPixel))
  342.  
  343. // Internal definitions
  344. #define _SET_PIXEL(array, index, bitsPerPixel, color)                          \
  345.                 array[index/(8/bitsPerPixel)] = (                              \
  346.                         array[index/(8/bitsPerPixel)] &                        \
  347.                         ~(((1<<bitsPerPixel)-1) << ((index * bitsPerPixel)%8)) \
  348.                 ) | color << ((index * bitsPerPixel)%8)
  349.  
  350.  
  351. #define _GET_PIXEL(array, index, bitsPerPixel) (                               \
  352.                         array[index/(8/bitsPerPixel)] >>(index*bitsPerPixel)%8 \
  353.                 ) & ((1<<bitsPerPixel)-1)
  354.  
  355.  
  356. ////////////////////////////////////////////////////////////////////////////////
  357. /// @brief Conversion between cycles and nano seconds
  358. ////////////////////////////////////////////////////////////////////////////////
  359. #define NS_PER_SEC          1000000000ULL
  360. #define CYCLES_PER_SEC      ((uint64_t) (F_CPU))
  361. #define CYCLES(time_ns)     (((CYCLES_PER_SEC * (time_ns)) + NS_PER_SEC - 1ULL) / NS_PER_SEC)
  362. #define NANOSECONDS(cycles) (((cycles) * NS_PER_SEC + CYCLES_PER_SEC-1) / CYCLES_PER_SEC)
  363.  
  364.  
  365. ////////////////////////////////////////////////////////////////////////////////
  366. /// @brief definitions for class template specializations
  367. ////////////////////////////////////////////////////////////////////////////////
  368.  
  369. /// @brief AVR ports are referenced A through F. For example ws2812b<D,6>
  370. enum avrLedStripPort {
  371.         A = 1,
  372.         B = 2,
  373.         C = 3,
  374.         D = 4,
  375.         E = 5,
  376.         F = 6
  377. };
  378.  
  379. /// @brief Pixel type declares the byte order for every color of the LED strip
  380. /// when using 24/32 bit typed pixels
  381. enum pixelFormat {
  382.         NONE = 0, // Defaults to 3 bytes per pixel of unspecified order
  383.         RGB  = 1,
  384.         GRB  = 2,
  385.         BGR  = 3,
  386.  
  387.         RGBW = 4,
  388.         GRBW = 5,
  389.         HBGR = 6
  390. };
  391. #define PIXEL_FORMAT_4B RGBW
  392.  
  393. /// @brief Type of low-level method to send data for the LED strip (see sendBytes)
  394. enum ledProtocol {
  395.         ONE_PORT_BITBANG = 1,   // Any LED with single data line
  396.         TWO_PORT_SPLIT_BITBANG = 2, // Same, but update 2 ports in parel, sending 1/2 the array to one port, and the other 1/2 to the other
  397.         TWO_PORT_INTLV_BITBANG = 3, // Same, but update 2 ports in parel, interleaving the pixels of the array
  398.         EIGHT_PORT_BITBANG = 4, // Experimental
  399.         ONE_PORT_PWM = 5,       // Not implemented
  400.         ONE_PORT_UART = 6,      // Not implemented
  401.  
  402.         SPI_BITBANG = 7,        // APA-102 and any LED with data and clock line
  403.         SPI_HARDWARE = 8        // Not implemented
  404. };
  405. #define PROTOCOL_SPI SPI_BITBANG
  406.  
  407.  
  408. ////////////////////////////////////////////////////////////////////////////////
  409. /// @brief Hack to survive undefined port on Arduino
  410. /// avoid compilation errors for arduinos that are missing some of the 4 ports
  411. /// by defining  the unknown ports to be any of the known ones. This quiets
  412. /// the compiler, and that fluff code optimizes away.
  413. ////////////////////////////////////////////////////////////////////////////////
  414.  
  415. // Define a DUMMY_PORT_ID that will be used to patch unknown ports to map to
  416. // the first existing port we find. Undefined ports won't be used but this
  417. // lets the compiler work without complaining.
  418. #if defined(PORTD)
  419. #define DUMMY_PORT PORTD
  420. #define DUMMY_DDR   DDRD
  421. #elif defined(PORTB)
  422. #define DUMMY_PORT PORTB
  423. #define DUMMY_DDR   DDRB
  424. #elif defined(PORTA)
  425. #define DUMMY_PORT PORTA
  426. #define DUMMY_DDR   DDRA
  427. #elif defined(PORTC)
  428. #define DUMMY_PORT PORTC
  429. #define DUMMY_DDR   DDRC
  430. #endif // PORT
  431.  
  432. // If any of the ports we support does not exist, re-map it to the dummy port.
  433. #ifdef DUMMY_PORT
  434. #ifndef PORTA
  435. #define PORTA DUMMY_PORT
  436. #define  DDRA DUMMY_DDR
  437. #endif // PORTA
  438. #ifndef PORTB
  439. #define PORTB DUMMY_PORT
  440. #define  DDRB DUMMY_DDR
  441. #endif // PORTB
  442. #ifndef PORTC
  443. #define PORTC DUMMY_PORT
  444. #define  DDRC DUMMY_DDR
  445. #endif // PORTC
  446. #ifndef PORTD
  447. #define PORTD DUMMY_PORT
  448. #define  DDRD DUMMY_DDR
  449. #endif // PORTD
  450. #ifndef PORTE
  451. #define PORTE DUMMY_PORT
  452. #define  DDRE DUMMY_DDR
  453. #endif // PORTE
  454. #ifndef PORTF
  455. #define PORTF DUMMY_PORT
  456. #define  DDRF DUMMY_DDR
  457. #endif // PORTF
  458. #endif // DUMMY_PORT
  459.  
  460.  
  461. ////////////////////////////////////////////////////////////////////////////////
  462. #ifdef ARDUINO_ARCH_AVR
  463. ////////////////////////////////////////////////////////////////////////////////
  464. /// @brief Arduino AVR low level macros
  465. ////////////////////////////////////////////////////////////////////////////////
  466.  
  467. /// Port Data Direction control Register address
  468. #define AVR_DDR(id) _AVR_DDR((id))
  469. #define _AVR_DDR(id) ((id==A) ? DDRA : (id==B) ? DDRB : (id==C) ? DDRC : \
  470.                 (id==D) ? DDRD : (id==E) ? DDRE : DDRF)
  471. #define SET_DDR_HIGH( portId, portPin) AVR_DDR(portId)  |= 1U << portPin
  472. #define FAB_DDR(portId, val) AVR_DDR(portId) = val
  473.  
  474. /// Port address & pin level manipulation
  475. #define AVR_PORT(id) _AVR_PORT((id))
  476. #define _AVR_PORT(id) ((id==A) ? PORTA : (id==B) ? PORTB : (id==C) ? PORTC : \
  477.                 (id==D) ? PORTD : (id==E) ? PORTE : PORTF)
  478. #define FAB_PORT(portId, val) AVR_PORT(portId) = val
  479. // Note: gcc converts these bit manipulations to sbi and cbi instructions
  480. #define SET_PORT_HIGH(portId, portPin) AVR_PORT(portId) |= 1U << portPin
  481. #define SET_PORT_LOW( portId, portPin) AVR_PORT(portId) &= ~(1U << portPin);
  482.  
  483. /// Method to optimy delay N cycles with nops for bitBang.
  484. #define DELAY_CYCLES(count) if (count > 0) __builtin_avr_delay_cycles(count);
  485.  
  486. // Number of cycles sbi and cbi instructions take when using SET macros
  487. const int sbiCycles = 2;
  488. const int cbiCycles = 2;
  489.  
  490. #define DISABLE_INTERRUPTS {uint8_t oldSREG = SREG; __builtin_avr_cli()
  491. #define RESTORE_INTERRUPTS SREG = oldSREG; }
  492.  
  493.  
  494. ////////////////////////////////////////////////////////////////////////////////
  495. #elif defined(__arm__)
  496. ////////////////////////////////////////////////////////////////////////////////
  497. /// @brief ARM0 - ARM3 low level macros
  498. /// @note: Ports have no letter, just port pins. ws2812b<D,6> will ignore D and
  499. /// just route to pin 6.
  500. ///
  501. /// Register information:
  502. /// DWT_CYCCNT: Cycle count register
  503. ////////////////////////////////////////////////////////////////////////////////
  504.  
  505. /// @todo THE debug() function template resolution does not work on non optimized teensy
  506. //#define DISABLE_DEBUG_METHOD
  507.  
  508. #define SET_DDR_HIGH( portId, portPin)
  509. #define FAB_DDR( portId, val)
  510. #define FAB_PORT(portId, val)
  511.  
  512. #define SET_PORT_HIGH(portId, pinId)   digitalWriteFast(pinId, 1)
  513. #define SET_PORT_LOW( portId, pinId)   digitalWriteFast(pinId, 0)
  514.  
  515. /// Delay N cycles using cycles register
  516. #define DELAY_CYCLES(count) {int till = count + ARM_DWT_CYCCNT; while (ARM_DWT_CYCCNT < till);}
  517.  
  518. // Number of cycles sbi and cbi instructions take
  519. const int sbiCycles = 2;
  520. const int cbiCycles = 2;
  521.  
  522. #define DISABLE_INTERRUPTS {uint8_t oldSREG = SREG; cli()
  523. #define RESTORE_INTERRUPTS SREG = oldSREG; }
  524.  
  525. //mov r0, #COUNT
  526. //L:
  527. //subs r0, r0, #1
  528. //bnz L
  529. #define MACRO_CMB( A , B)           A##B
  530. #define M_RPT(__N, __macro)         MACRO_CMB(M_RPT, __N)(__macro)
  531. #define M_RPT0(__macro)
  532. #define M_RPT1(__macro)             M_RPT0(__macro)   __macro(0)
  533. #define M_RPT2(__macro)             M_RPT1(__macro)   __macro(1)
  534. //...
  535. #define MY_NOP(__N)                 __asm ("nop");
  536. #define delay150cycles M_RPT(150, MY_NOP);
  537.  
  538. ////////////////////////////////////////////////////////////////////////////////
  539. #elif defined(ESP8266)
  540.  
  541. #error "Unsupported Tensilica (ARC)Architecture"
  542.  
  543. #else
  544. ////////////////////////////////////////////////////////////////////////////////
  545. /// @brief unknown processor architecture
  546. ////////////////////////////////////////////////////////////////////////////////
  547.  
  548. #error "Unsupported Architecture"
  549.  
  550. ////////////////////////////////////////////////////////////////////////////////
  551. #endif // CPU ARCHITECTURE
  552. ////////////////////////////////////////////////////////////////////////////////
  553.  
  554.  
  555.  
  556. ////////////////////////////////////////////////////////////////////////////////
  557. // Base class defining LED strip operations owed.
  558. ////////////////////////////////////////////////////////////////////////////////
  559. static const uint8_t blank[3] = {128,128,128};
  560.  
  561. #define FAB_TDEF int16_t high1,             \
  562.                 int16_t low1,               \
  563.                 int16_t high0,              \
  564.                 int16_t low0,               \
  565.                 uint32_t minMsRefresh,      \
  566.                 avrLedStripPort dataPortId, \
  567.                 uint8_t dataPortPin,        \
  568.                 avrLedStripPort clockPortId,\
  569.                 uint8_t clockPortPin,       \
  570.                 pixelFormat colors,         \
  571.                 ledProtocol protocol
  572.  
  573. #define FAB_TVAR high1, low1, high0, low0, minMsRefresh, dataPortId, dataPortPin, clockPortId, clockPortPin, colors, protocol
  574.  
  575. /// @brief Class to drive LED strips. Relies on custom sendBytes() method to push data to LEDs
  576. //template<
  577. //      int16_t high1,          // Number of cycles high for logical one
  578. //      int16_t low1,           // Number of cycles  low for logical one
  579. //      int16_t high0,          // Number of cycles high for logical zero
  580. //      int16_t low0,           // Number of cycles  low for logical zero
  581. //      uint32_t minMsRefresh,  // Minimum milliseconds to wait to reset LED strip data stream
  582. //      avrLedStripPort dataPortId, // AVR port the LED strip is attached to
  583. //      uint8_t dataPortPin         // AVR port bit the LED strip is attached to
  584. //>
  585. template <FAB_TDEF>
  586. class avrBitbangLedStrip
  587. {
  588.         static const uint8_t bytesPerPixel = (colors < PIXEL_FORMAT_4B) ? 3 : 4;
  589.  
  590.         public:
  591.         ////////////////////////////////////////////////////////////////////////
  592.         /// @brief Constructor: Set ed dataPortId.dataPortPin to digital output
  593.         ////////////////////////////////////////////////////////////////////////
  594.         avrBitbangLedStrip();
  595.         ////////////////////////////////////////////////////////////////////////
  596.         ~avrBitbangLedStrip() { };
  597.  
  598.         ////////////////////////////////////////////////////////////////////////
  599.         /// @brief Prints to console the configuration
  600.         /// @note You must implement the print routines (see example)
  601.         ////////////////////////////////////////////////////////////////////////
  602.         template <void printChar(const char *),void printInt(uint32_t)>
  603. #ifndef DISABLE_DEBUG_METHOD
  604.         static inline void debug(void);
  605. #endif
  606.  
  607.         ////////////////////////////////////////////////////////////////////////
  608.         /// @brief Sends N bytes to the LED using bit-banging.
  609.         ///
  610.         /// @param[in] count Number of bytes sent
  611.         /// @param[in] array Array of bytes to send
  612.         ///
  613.         /// @warning
  614.         /// The cer must handle interupts!
  615.         /// If interupts are not off, the timer interupt will happen, and it takes
  616.         /// too long and will cause a LED strip reset.
  617.         ///
  618.         /// @note
  619.         /// __attribute__ ((always_inline)) forces gcc to inline this function in
  620.         /// the cer, to optimize there and avoid function c overhead. The
  621.         /// timing is critical at 16MHz.
  622.         /// @note
  623.         /// __builtin_avr_delay_cycles() is a gcc built-in that will generate ASM
  624.         /// to implement the exact number of cycle delays specified using the most
  625.         /// compact instruction loop, and is portable.
  626.         /// @note
  627.         /// The AVR port bit-set math will be changed by gcc to a sbi/cbi in ASM
  628.         ////////////////////////////////////////////////////////////////////////
  629.         static inline void
  630.         sendBytes(const uint16_t count, const uint8_t * array)
  631.         __attribute__ ((always_inline));
  632.  
  633.         ////////////////////////////////////////////////////////////////////////
  634.         /// @brief Sends N uint32_t in a row set to zero or 0xFFFFFFFF, to build
  635.         /// a frame for each pixel, and for a whole strip, SPI protocol only
  636.         ////////////////////////////////////////////////////////////////////////
  637.         static inline void
  638.         spiSoftwareSendFrame(const uint16_t count, bool high)
  639.         __attribute__ ((always_inline));
  640.  
  641.         ////////////////////////////////////////////////////////////////////////
  642.         /// @bried Implements sendBytes for the 1-port SPI protocol
  643.         ////////////////////////////////////////////////////////////////////////
  644.         static inline void
  645.         spiSoftwareSendBytes(const uint16_t count, const uint8_t * array)
  646.         __attribute__ ((always_inline));
  647.  
  648.         ////////////////////////////////////////////////////////////////////////
  649.         /// @brief Implements sendBytes for the 1-ports protocol
  650.         ////////////////////////////////////////////////////////////////////////
  651.         static inline void
  652.         onePortSoftwareSendBytes(const uint16_t count, const uint8_t * array)
  653.         __attribute__ ((always_inline));
  654.  
  655.         ////////////////////////////////////////////////////////////////////////
  656.         /// @brief Implements sendBytes for the 2-ports protocol
  657.         ////////////////////////////////////////////////////////////////////////
  658.         static inline void
  659.         twoPortSoftwareSendBytes(const uint16_t count, const uint8_t * array)
  660.         __attribute__ ((always_inline));
  661.  
  662.         ////////////////////////////////////////////////////////////////////////
  663.         /// @brief Implements sendBytes for the 8-ports protocol
  664.         ////////////////////////////////////////////////////////////////////////
  665.         static inline void
  666.         eightPortSoftwareSendBytes(const uint16_t count, const uint8_t * array)
  667.         __attribute__ ((always_inline));
  668.  
  669.         ////////////////////////////////////////////////////////////////////////
  670.         /// @brief Clears the LED strip
  671.         /// @param[in] numPixels  Number of pixels to erase
  672.         ////////////////////////////////////////////////////////////////////////
  673.         static inline void clear( const uint16_t numPixels)
  674.         __attribute__ ((always_inline));
  675.  
  676.         ////////////////////////////////////////////////////////////////////////
  677.         /// @brief Sets the LED strip to a grey value
  678.         /// @param[in] numPixels  Number of pixels to erase
  679.         /// @param[in] value      Brightness of the grey [0..255]
  680.         ////////////////////////////////////////////////////////////////////////
  681.         static inline void grey(
  682.                         const uint16_t numPixels,
  683.                         const uint8_t value)
  684.         __attribute__ ((always_inline));
  685.  
  686.         ////////////////////////////////////////////////////////////////////////
  687.         /// @brief Sends an array of 32bit words encoding 0x00bbrrgg to the LEDs
  688.         /// This is the standard encoding for most libraries and wastes 25% of
  689.         /// the SRAM.
  690.         ///
  691.         /// @param[in] numPixels Number of pixels to write
  692.         /// @param[in] array     Array of 1 word per pixels in native order
  693.         ///                      (most significant byte is ignored)
  694.         ////////////////////////////////////////////////////////////////////////
  695.         static inline void sendPixels(
  696.                         const uint16_t numPixels,
  697.                         const uint32_t * pixelArray)
  698.         __attribute__ ((always_inline));
  699.  
  700.         ////////////////////////////////////////////////////////////////////////
  701.         /// @brief Sends 3-byte pixels to the LED strip.
  702.         /// This function should be the most common used method.
  703.         ///
  704.         /// @note for SK6812, which uses 4 bytes per pixels, this method will send
  705.         /// 4 bytes per pixel and expect an array containing 4 bytes per pixel.
  706.         /// @param[in] numPixels Number of pixels to write
  707.         /// @param[in] array     Array of 3-bytes per pixels in native order
  708.         ///                      (for example GBR for WS2812B LED strips)
  709.         ////////////////////////////////////////////////////////////////////////
  710.         static inline void sendPixels(
  711.                         const uint16_t numPixels,
  712.                         const uint8_t * array) __attribute__ ((always_inline));
  713.  
  714.         static inline void sendPixels(
  715.                         const uint16_t numPixels,
  716.                         const rgbw * array) __attribute__ ((always_inline));
  717.  
  718.         static inline void sendPixels(
  719.                         const uint16_t numPixels,
  720.                         const grbw * array) __attribute__ ((always_inline));
  721.  
  722.         static inline void sendPixels(
  723.                         const uint16_t numPixels,
  724.                         const hbgr * array) __attribute__ ((always_inline));
  725.  
  726.         static inline void sendPixels(
  727.                         const uint16_t numPixels,
  728.                         const rgb * array) __attribute__ ((always_inline));
  729.  
  730.         static inline void sendPixels(
  731.                         const uint16_t numPixels,
  732.                         const grb * array) __attribute__ ((always_inline));
  733.  
  734.         static inline void sendPixels(
  735.                         const uint16_t numPixels,
  736.                         const bgr * array) __attribute__ ((always_inline));
  737.  
  738.         ////////////////////////////////////////////////////////////////////////
  739.         /// @brief Sends an array of bits encoded with a palette to the LEDs.
  740.         /// This is a compact method to store patterns, compressed 3x to 24x,
  741.         /// but with the overhead of a palette array.
  742.         ///
  743.         /// @param[in] count   Size of the array in bytes
  744.         /// @param[in] array   Array of bitsPerPixel bits per pixels, where the
  745.         ///                    number of bits is 1,2, 4 or 8.
  746.         /// @param[in] palette Palette array with one entry per color used.
  747.         ///
  748.         /// 1bit  ->   6B palette
  749.         /// 2bits ->  12B palette
  750.         /// 4bits ->  48B palette
  751.         /// 8bits -> 768B palette
  752.         ///
  753.         /// @note bitsPerPixel is a template constant to ow the compiler to
  754.         /// optimize the bit-masking code.
  755.         ////////////////////////////////////////////////////////////////////////
  756.         template <const uint8_t bitsPerPixel, class pixelColors> // @note does not support uint32_t uint8_t.
  757.         static inline void sendPixels (
  758.                         const uint16_t count,
  759.                         const uint8_t * pixelArray,
  760.                         const uint8_t * reds,
  761.                         const uint8_t * greens,
  762.                         const uint8_t * blues) __attribute__ ((always_inline));
  763.  
  764.         template <const uint8_t bitsPerPixel>
  765.         static inline void sendPixels (
  766.                         const uint16_t count,
  767.                         const uint8_t * pixelArray,
  768.                         const uint8_t * palette) __attribute__ ((always_inline));
  769.  
  770.         template <const uint8_t bitsPerPixel, class paletteColors>
  771.         static inline void sendPixels (
  772.                         const uint16_t count,
  773.                         const uint8_t * pixelArray,
  774.                         const paletteColors * palette) __attribute__ ((always_inline));
  775.  
  776.         ////////////////////////////////////////////////////////////////////////
  777.         /// @brief Send an array that is remapped to a physical LED strip
  778.         /// of a different layout than the natural layout of the pixel array
  779.         /// @param[in] pixelMap An array mapping a physical pixel to an offset
  780.         ///            in the array pixelMap[pix] = index
  781.         /// Note: the array size is not used as it is expected that it will be
  782.         /// at least as big as the largest index in the pixel map.
  783.         ////////////////////////////////////////////////////////////////////////
  784.         template <class pixelType>
  785.         static inline void sendPixelsRemap(
  786.                         const uint16_t numPixels,
  787.                         const uint16_t * pixelMap,
  788.                         const pixelType * array) __attribute__ ((always_inline));
  789.  
  790.         template <const uint8_t bitsPerPixel, class pixelType>
  791.         static inline void sendPixelsRemap (
  792.                         const uint16_t numPixels,
  793.                         const uint16_t * pixelMap,
  794.                         const uint8_t * pixelArray,
  795.                         const pixelType * palette) __attribute__ ((always_inline));
  796.  
  797.         template <const uint8_t bitsPerPixel, class pixelType>
  798.         static inline void sendPixelsRemap (
  799.                         const uint8_t numPixels,
  800.                         const uint8_t * pixelMap,
  801.                         const uint8_t * pixelArray,
  802.                         const pixelType * palette) __attribute__ ((always_inline));
  803.  
  804.  
  805.         ////////////////////////////////////////////////////////////////////////
  806.         /// @brief Sends an array of 3 pixels per 16bit words to the LEDs
  807.         /// This yelds 32K colors, and saves 33% RAM without using a palette.
  808.         ///
  809.         /// the SRAM.
  810.         /// @brief Sends an array of 16-bit words to the LEDs. Each word encodes
  811.         /// one pixel with 64 levels (5 bits)
  812.         //
  813.         /// @note brightness is a template constant that controls the unused 3
  814.         /// bits of the color. Its value is  zero to 2. Often set to 0 when
  815.         /// LED strip is too bright.
  816.         ////////////////////////////////////////////////////////////////////////
  817.         template <uint8_t brightness>
  818.         static inline void sendPixels(int count, uint16_t * pixelArray) __attribute__ ((always_inline));
  819.  
  820.  
  821.  
  822.         ////////////////////////////////////////////////////////////////////////
  823.         /// @brief Waits long enough to trigger a LED strip reset
  824.         ////////////////////////////////////////////////////////////////////////
  825.         static inline void refresh() {
  826.                 if (protocol == SPI_BITBANG) {
  827.                         // SPI: Reset LED strip to accept a refresh with 32bit start frame
  828.                         // set to zero, and an end frame set to 0 or 0xFF (we use zero)
  829.                         // of 16B supporting up to 256 pixels
  830.                         spiSoftwareSendFrame(4+16, false);
  831.                 } else {
  832.                         // 1-wire: Delay next pixels to cause a refresh
  833.                         delay(minMsRefresh);
  834.                 }
  835.         }
  836. };
  837.  
  838.  
  839. ////////////////////////////////////////////////////////////////////////////////
  840. /// Class methods definition
  841. ////////////////////////////////////////////////////////////////////////////////
  842.  
  843. ////////////////////////////////////////////////////////////////////////
  844. template<FAB_TDEF>
  845. avrBitbangLedStrip<FAB_TVAR>::avrBitbangLedStrip()
  846. {
  847.         // Digital out pin mode
  848.         // bitSet(portDDR, dataPortPin);
  849.         // DDR? |= 1U << dataPortPin;
  850.         switch (protocol) {
  851.                 case TWO_PORT_SPLIT_BITBANG:
  852.                 case TWO_PORT_INTLV_BITBANG:
  853.                         // Init two ports as out, set to low state
  854.                         SET_DDR_HIGH(dataPortId,  dataPortPin);
  855.                         SET_DDR_HIGH(clockPortId, clockPortPin);
  856.                         SET_PORT_LOW(dataPortId,  dataPortPin);
  857.                         SET_PORT_LOW(clockPortId, clockPortPin);
  858.                         break;
  859.                 case EIGHT_PORT_BITBANG:
  860.                         FAB_DDR(dataPortId, 0xFF); //  pins out
  861.                         FAB_PORT(dataPortId, 0x00); //  pins low
  862.                         break;
  863.                 case SPI_BITBANG:
  864.                         // Init both ports as out
  865.                         SET_DDR_HIGH(dataPortId, dataPortPin);
  866.                         SET_DDR_HIGH(clockPortId, clockPortPin);
  867.                         // SPI: Reset LED strip to accept a refresh
  868.                         spiSoftwareSendFrame(16, false);
  869.                         break;
  870.                 default:
  871.                         // Init data port as out, set to low state
  872.                         SET_DDR_HIGH(dataPortId, dataPortPin);
  873.                         SET_PORT_LOW(dataPortId, dataPortPin);
  874.                         break;
  875.         }
  876. };
  877.  
  878. #ifndef DISABLE_DEBUG_METHOD
  879. template<FAB_TDEF>
  880. template <void printChar(const char *),void printInt(uint32_t)>
  881. inline void
  882. avrBitbangLedStrip<FAB_TVAR>::debug(void)
  883. {
  884.         printChar("\nclass avrBitbangLedStrip<...>\n");
  885.  
  886.         printInt(CYCLES_PER_SEC/1000000);
  887.         printChar("MHz CPU, ");
  888.         printInt(NANOSECONDS(1000));
  889.         printChar(" picoseconds per cycle\n");
  890.  
  891.         printChar("ONE  HIGH=");
  892.         printInt(high1);
  893.         printChar(" LOW=");
  894.         printInt(low1);
  895.         printChar(" cycles\n");
  896.  
  897.         printChar("ZERO HIGH=");
  898.         printInt(high0);
  899.         printChar(" LOW=");
  900.         printInt(low0);
  901.         printChar(" cycles\n");
  902.  
  903.         switch (colors) {
  904.                 case NONE: printChar("NONE"); break;
  905.                 case RGB: printChar("RGB"); break;
  906.                 case GRB: printChar("GRB"); break;
  907.                 case BGR: printChar("BGR"); break;
  908.                 case RGBW: printChar("RGBW"); break;
  909.                 case GRBW: printChar("GRBW"); break;
  910.                 case HBGR: printChar("HBGR"); break;
  911.                 default: printChar("ERROR!"); break;
  912.         }
  913.  
  914.         printChar(" REFRESH MSEC=");
  915.         printInt(minMsRefresh);
  916.  
  917.         printChar("\nDATA_PORT ");
  918.         switch(dataPortId) {
  919.                 case A:
  920.                         printChar("A.");
  921.                         break;
  922.                 case B:
  923.                         printChar("B.");
  924.                         break;
  925.                 case C:
  926.                         printChar("C.");
  927.                         break;
  928.                 case D:
  929.                         printChar("D.");
  930.                         break;
  931.                 case E:
  932.                         printChar("E.");
  933.                         break;
  934.                 case F:
  935.                         printChar("F.");
  936.                         break;
  937.                 default:
  938.                         printChar("UNKNOWN.");
  939.         }
  940.         printInt(dataPortPin);
  941.         printChar(", ");
  942.  
  943.         if (protocol >= PROTOCOL_SPI) {
  944.                 printChar("CLOCK_PORT ");
  945.                 switch(clockPortId) {
  946.                         case A:
  947.                                 printChar("A.");
  948.                                 break;
  949.                         case B:
  950.                                 printChar("B.");
  951.                                 break;
  952.                         case C:
  953.                                 printChar("C.");
  954.                                 break;
  955.                         case D:
  956.                                 printChar("D.");
  957.                                 break;
  958.                         case E:
  959.                                 printChar("E.");
  960.                                 break;
  961.                         case F:
  962.                                 printChar("F.");
  963.                                 break;
  964.                         default:
  965.                                 printChar("UNKNOWN.");
  966.                 }
  967.                 printInt(clockPortPin);
  968.                 printChar(", ");
  969.         }
  970.  
  971.         switch(protocol) {
  972.                 case ONE_PORT_BITBANG:
  973.                         printChar("ONE-PORT (bitbang)");
  974.                         break;
  975.                 case TWO_PORT_SPLIT_BITBANG:
  976.                         printChar("TWO-PORT-SPLIT (bitbang)");
  977.                         break;
  978.                 case TWO_PORT_INTLV_BITBANG:
  979.                         printChar("TWO-PORT-INTERLEAVED (bitbang)");
  980.                         break;
  981.                 case EIGHT_PORT_BITBANG:
  982.                         printChar("HEIGHT-PORT (bitbang)");
  983.                         break;
  984.                 case ONE_PORT_PWM:
  985.                         printChar("ONE-PORT (PWM)");
  986.                         break;
  987.                 case ONE_PORT_UART:
  988.                         printChar("ONE-PORT (UART)");
  989.                         break;
  990.                 case SPI_BITBANG:
  991.                         printChar("SPI (bitbang)");
  992.                         break;
  993.                 case SPI_HARDWARE:
  994.                         printChar("SPI (hardware)");
  995.                         break;
  996.                 default:
  997.                         printChar("PROTOCOL UNKNOWN");
  998.         }
  999.         printChar("\n");
  1000. }
  1001. #endif
  1002.  
  1003. template<FAB_TDEF>
  1004. inline void
  1005. avrBitbangLedStrip<FAB_TVAR>::sendBytes(const uint16_t count, const uint8_t * array)
  1006. {
  1007.         switch (protocol) {
  1008.                 case ONE_PORT_BITBANG:
  1009.                         onePortSoftwareSendBytes(count, array);
  1010.                         break;
  1011.                 case TWO_PORT_SPLIT_BITBANG:
  1012.                 case TWO_PORT_INTLV_BITBANG:
  1013.                         // Note: the function will detect and handle modes I and S
  1014.                         twoPortSoftwareSendBytes(count, array);
  1015.                         break;
  1016.                 case EIGHT_PORT_BITBANG:
  1017.                         eightPortSoftwareSendBytes(count, array);
  1018.                         break;
  1019.                 case SPI_BITBANG:
  1020.                         spiSoftwareSendBytes(count, array);
  1021.                         break;
  1022.         }
  1023. }
  1024.  
  1025. template<FAB_TDEF>
  1026. inline void
  1027. avrBitbangLedStrip<FAB_TVAR>::spiSoftwareSendFrame(const uint16_t count, bool high)
  1028. {
  1029.         if (high) {
  1030.                 SET_PORT_HIGH(dataPortId, dataPortPin);
  1031.         } else {
  1032.                 SET_PORT_LOW(dataPortId, dataPortPin);
  1033.         }
  1034.         // for(uint32_t c = 0; c < 32 * count; c++) {
  1035.         for(uint32_t c = 0; c < 8 * count; c++) {
  1036.                 SET_PORT_LOW(clockPortId, clockPortPin);
  1037.                 SET_PORT_HIGH(clockPortId, clockPortPin);
  1038.         }
  1039. }
  1040.  
  1041. template<FAB_TDEF>
  1042. inline void
  1043. avrBitbangLedStrip<FAB_TVAR>::spiSoftwareSendBytes(const uint16_t count, const uint8_t * array)
  1044. {
  1045.         for(uint16_t cnt = 0; cnt < count; ++cnt) {
  1046.                 const uint8_t val = array[cnt];
  1047.                 // If LED strip is defined as 3 byte type (default) then hard code the first
  1048.                 // byte to 0xFF, aka max brightness.
  1049.                 // This hard-codes the APA-102 protocol here so it is a bit hacky.
  1050.                 if ((colors >= PIXEL_FORMAT_4B) && ((cnt % 3) == 0)) {
  1051. //                      spiSoftwareSendFrame(1, true);
  1052.                 }
  1053.                 // To send a bit to SPI, set its value, then transtion clock low-high
  1054.                 for(int8_t b=7; b>=0; b--) {
  1055.                         const bool bit = (val>>b) & 0x1;
  1056.                         SET_PORT_LOW(clockPortId, clockPortPin);
  1057.                         if (bit) {
  1058.                                 SET_PORT_HIGH(dataPortId, dataPortPin);
  1059.                         } else {
  1060.                                 SET_PORT_LOW(dataPortId, dataPortPin);
  1061.                         }
  1062.                         SET_PORT_HIGH(clockPortId, clockPortPin);
  1063.                 }
  1064.  
  1065.         }
  1066. }
  1067.  
  1068. /// @brief sends the array split across two ports each having half the LED strip to illuminate.
  1069. /// To achieve this, we repurpose the clock port used for SPI as a second data port.
  1070. /// We support two protocols:
  1071. /// TWO_PORT_SPLIT_BITBANG: The array is split into 2 halves sent each sent to one of the ports
  1072. /// TWO_PORT_INTLV_BITBANG: The array is interleaved and each pixel of 3 byte is sent to the next port
  1073. template<FAB_TDEF>
  1074. inline void
  1075. avrBitbangLedStrip<FAB_TVAR>::twoPortSoftwareSendBytes(const uint16_t count, const uint8_t * array)
  1076. {
  1077.         // Number of bytes per pixel
  1078.         const uint16_t bpp =  (colors < PIXEL_FORMAT_4B) ? 3 : 4;
  1079.  
  1080.         // If split mode, we send a block of half size
  1081.         const uint16_t blockSize = (protocol == TWO_PORT_SPLIT_BITBANG) ? count/2 : count;
  1082.  
  1083.         // Stride is two for interlacing to jump pixels going to the other port
  1084.         const uint8_t stride = (protocol == TWO_PORT_SPLIT_BITBANG) ? 1 : 2;
  1085.         const uint8_t increment = stride * bpp;
  1086.  
  1087.         // Loop to scan  pixels, potentiy skipping every other pixel, or scanning 1/2 the pixels
  1088.         // based on the display protocol used.
  1089.         for(uint16_t pix = 0; pix < blockSize; pix += increment) {
  1090.                 // Loop to send 3 or 4 bytes of a pixel to the same port
  1091.                 for(uint16_t pos = pix; pos < pix+bpp; pos++) {
  1092.                         for(int8_t bit = 7; bit >= 0; bit--) {
  1093.                                 const uint8_t mask = 1 << bit;
  1094.  
  1095.                                 volatile bool isbitDhigh = array[pos] & mask;
  1096.        
  1097.                                 volatile bool isbitChigh = (protocol == TWO_PORT_SPLIT_BITBANG) ?
  1098.                                         array[pos + blockSize] & mask : // split: pixel is blockSize away.
  1099.                                         array[pos + bpp] & mask;        // interleaved: pixel is next one.
  1100.  
  1101.                                 if (isbitDhigh) SET_PORT_HIGH(dataPortId, dataPortPin);
  1102.                                 if (isbitChigh) SET_PORT_HIGH(clockPortId, clockPortPin);
  1103.  
  1104.                                 if (!isbitDhigh) {
  1105.                                         SET_PORT_HIGH(dataPortId, dataPortPin);
  1106.                                         DELAY_CYCLES(high0 - sbiCycles);
  1107.                                         SET_PORT_LOW(dataPortId, dataPortPin);
  1108.                                 }
  1109.                                 if (!isbitChigh) {
  1110.                                         SET_PORT_HIGH(clockPortId, clockPortPin);
  1111.                                         DELAY_CYCLES(high0 - sbiCycles);
  1112.                                         SET_PORT_LOW(clockPortId, clockPortPin);
  1113.                                 }
  1114.                                 DELAY_CYCLES(high1 - 2*sbiCycles);
  1115.                                 SET_PORT_LOW(dataPortId, dataPortPin);
  1116.                                 SET_PORT_LOW(clockPortId, clockPortPin);
  1117.                                 DELAY_CYCLES(low1 - 2*cbiCycles);
  1118.                         }
  1119.                 }
  1120.         }
  1121. }
  1122.  
  1123. #if 0
  1124. template<FAB_TDEF>
  1125. inline void
  1126. avrBitbangLedStrip<FAB_TVAR>::twoPortSoftwareSendBytes(const uint16_t count, const uint8_t * array)
  1127. {
  1128.         const uint16_t blockSize = count/2;
  1129.         for(uint16_t pos = 0; pos < blockSize; pos++) {
  1130.                 for(int8_t bit = 7; bit >= 0; bit--) {
  1131.                         const uint8_t mask = 1 << bit;
  1132.                         const bool isbitDhigh = array[0*blockSize + pos] & mask;
  1133.                         const bool isbitChigh = array[1*blockSize + pos] & mask;
  1134.                         if (isbitDhigh) SET_PORT_HIGH(dataPortId, dataPortPin);
  1135.                         if (isbitChigh) SET_PORT_HIGH(clockPortId, clockPortPin);
  1136.                         if (!isbitDhigh) {
  1137.                                 SET_PORT_HIGH(dataPortId, dataPortPin);
  1138.                                 //DELAY_CYCLES(high0 - sbiCycles);
  1139.                                 DELAY_CYCLES(0);
  1140.                                 SET_PORT_LOW(dataPortId, dataPortPin);
  1141.                         }
  1142.                         if (!isbitChigh) {
  1143.                                 SET_PORT_HIGH(clockPortId, clockPortPin);
  1144.                                 //DELAY_CYCLES(high0 - sbiCycles);
  1145.                                 DELAY_CYCLES(0);
  1146.                                 SET_PORT_LOW(clockPortId, clockPortPin);
  1147.                         }
  1148.                         DELAY_CYCLES(0);
  1149.                         SET_PORT_LOW(dataPortId, dataPortPin);
  1150.                         SET_PORT_LOW(clockPortId, clockPortPin);
  1151.                         DELAY_CYCLES(0);
  1152.                 }
  1153.         }
  1154. }
  1155. #endif
  1156.  
  1157.  
  1158. template<FAB_TDEF>
  1159. inline void
  1160. avrBitbangLedStrip<FAB_TVAR>::eightPortSoftwareSendBytes(const uint16_t count, const uint8_t * array)
  1161. {
  1162.         const uint16_t bpp =  (colors < PIXEL_FORMAT_4B) ? 3 : 4;
  1163.         const uint16_t blockSize __asm__("r14") = count / (clockPortPin - dataPortPin + 1) / bpp * bpp;
  1164.  
  1165.         // Buffer one byte of each port in register
  1166.         uint8_t r0 = 0; // __asm__("r2") = 0;
  1167.         uint8_t r1 = 0; // __asm__("r3") = 0;
  1168.         uint8_t r2 = 0; // __asm__("r4") = 0;
  1169.         uint8_t r3 = 0; // __asm__("r5") = 0;
  1170.         uint8_t r4 = 0; // __asm__("r6") = 0;
  1171.         uint8_t r5 = 0; // __asm__("r7") = 0;
  1172.         uint8_t r6 = 0; // __asm__("r8") = 0;
  1173.         uint8_t r7 = 0; // __asm__("r9") = 0;
  1174.  
  1175.         // Since bits for each port are sent delayed by one cycle to
  1176.         // implement the memory access pipeline, we must leave the
  1177.         // ports not yet in use set to LOW level. Once the pipeline
  1178.         // is initialized fully onMask == 0xFF, and we always set it
  1179.         // to high to send a zero or a one.
  1180.         uint8_t onMask __asm__("r10") = 0;
  1181.  
  1182.         for(uint16_t c __asm__("r12") = 0; c < blockSize ; ++c) {
  1183.                 for(int8_t b __asm__("r13") = 7; b >= 0; --b) {
  1184.                         uint8_t bitmask __asm__("r10") = 0;
  1185.  
  1186.                         // Load ONE byte per iteration
  1187.                         // Skip end condition check to reduce CPU cycles.
  1188.                         // It is expected that the LED strip won't have extra pixels.
  1189.                         switch (b) {
  1190.                                 case 0:
  1191.                                         // By checking staticy if rX is read  memory, we
  1192.                                         // avoid changing it, and the compiler will optimize out
  1193.                                         // the code including bitmask setting. On 16MHz Uno, we can
  1194.                                         // only set bitmask for 6 ports before the strip resets.
  1195.                                         if (0 == dataPortPin) {
  1196.                                                 onMask |= 1;
  1197.                                                 r0 = array[c];
  1198.                                         }
  1199.  
  1200.                                         if (r0 & 0b10000000) bitmask |= 1;
  1201.                                         if (r1 & 0b01000000) bitmask |= 2;
  1202.                                         if (r2 & 0b00100000) bitmask |= 4;
  1203.                                         if (r3 & 0b00010000) bitmask |= 8;
  1204.                                         if (r4 & 0b00001000) bitmask |= 16;
  1205.                                         if (r5 & 0b00000100) bitmask |= 32;
  1206.                                         if (r6 & 0b00000010) bitmask |= 64;
  1207.                                         if (r7 & 0b00000001) bitmask |= 128;
  1208.                                         break;
  1209.                                 case 1:
  1210.                                         if ((1 >= dataPortPin) && (1 <= clockPortPin)) {
  1211.                                                 onMask |= 2;
  1212.                                                 r1 = array[c + (1-dataPortPin) * blockSize];
  1213.                                         }
  1214.  
  1215.                                         if (r0 & 0b00000001) bitmask |= 1;
  1216.                                         if (r1 & 0b10000000) bitmask |= 2;
  1217.                                         if (r2 & 0b01000000) bitmask |= 4;
  1218.                                         if (r3 & 0b00100000) bitmask |= 8;
  1219.                                         if (r4 & 0b00010000) bitmask |= 16;
  1220.                                         if (r5 & 0b00001000) bitmask |= 32;
  1221.                                         if (r6 & 0b00000100) bitmask |= 64;
  1222.                                         if (r7 & 0b00000010) bitmask |= 128;
  1223.                                         break;
  1224.                                 case 2:
  1225.                                         if ((2 >= dataPortPin) && (2 <= clockPortPin)) {
  1226.                                                 onMask |= 4;
  1227.                                                 r2 = array[c + (2-dataPortPin) * blockSize];
  1228.                                         }
  1229.  
  1230.                                         if (r0 & 0b00000010) bitmask |= 1;
  1231.                                         if (r1 & 0b00000001) bitmask |= 2;
  1232.                                         if (r2 & 0b10000000) bitmask |= 4;
  1233.                                         if (r3 & 0b01000000) bitmask |= 8;
  1234.                                         if (r4 & 0b00100000) bitmask |= 16;
  1235.                                         if (r5 & 0b00010000) bitmask |= 32;
  1236.                                         if (r6 & 0b00001000) bitmask |= 64;
  1237.                                         if (r7 & 0b00000100) bitmask |= 128;
  1238.                                         break;
  1239.                                 case 3:
  1240.                                         if ((3 >= dataPortPin) && (3 <= clockPortPin)) {
  1241.                                                 onMask |= 8;
  1242.                                                 r3 = array[c + (3-dataPortPin) * blockSize];
  1243.                                         }
  1244.  
  1245.                                         if (r0 & 0b00000100) bitmask |= 1;
  1246.                                         if (r1 & 0b00000010) bitmask |= 2;
  1247.                                         if (r2 & 0b00000001) bitmask |= 4;
  1248.                                         if (r3 & 0b10000000) bitmask |= 8;
  1249.                                         if (r4 & 0b01000000) bitmask |= 16;
  1250.                                         if (r5 & 0b00100000) bitmask |= 32;
  1251.                                         if (r6 & 0b00010000) bitmask |= 64;
  1252.                                         if (r7 & 0b00001000) bitmask |= 128;
  1253.                                         break;
  1254.                                 case 4:
  1255.                                         if ((4 >= dataPortPin) && (4 <= clockPortPin)) {
  1256.                                                 onMask |= 16;
  1257.                                                 r4 = array[c + (4-dataPortPin) * blockSize];
  1258.                                         }
  1259.  
  1260.                                         if (r0 & 0b00001000) bitmask |= 1;
  1261.                                         if (r1 & 0b00000100) bitmask |= 2;
  1262.                                         if (r2 & 0b00000010) bitmask |= 4;
  1263.                                         if (r3 & 0b00000001) bitmask |= 8;
  1264.                                         if (r4 & 0b10000000) bitmask |= 16;
  1265.                                         if (r5 & 0b01000000) bitmask |= 32;
  1266.                                         if (r6 & 0b00100000) bitmask |= 64;
  1267.                                         if (r7 & 0b00010000) bitmask |= 128;
  1268.                                         break;
  1269.                                 case 5:
  1270.                                         if ((5 >= dataPortPin) && (5 <= clockPortPin)) {
  1271.                                                 onMask |= 32;
  1272.                                                 r5 = array[c + (5-dataPortPin) * blockSize];
  1273.                                         }
  1274.  
  1275.                                         if (r0 & 0b00010000) bitmask |= 1;
  1276.                                         if (r1 & 0b00001000) bitmask |= 2;
  1277.                                         if (r2 & 0b00000100) bitmask |= 4;
  1278.                                         if (r3 & 0b00000010) bitmask |= 8;
  1279.                                         if (r4 & 0b00000001) bitmask |= 16;
  1280.                                         if (r5 & 0b10000000) bitmask |= 32;
  1281.                                         if (r6 & 0b01000000) bitmask |= 64;
  1282.                                         if (r7 & 0b00100000) bitmask |= 128;
  1283.                                         break;
  1284.                                 case 6:
  1285.                                         if ((6 >= dataPortPin) && (6 <= clockPortPin)) {
  1286.                                                 onMask |= 64;
  1287.                                                 r6 = array[c + (6-dataPortPin) * blockSize];
  1288.                                         }
  1289.  
  1290.                                         if (r0 & 0b00100000) bitmask |= 1;
  1291.                                         if (r1 & 0b00010000) bitmask |= 2;
  1292.                                         if (r2 & 0b00001000) bitmask |= 4;
  1293.                                         if (r3 & 0b00000100) bitmask |= 8;
  1294.                                         if (r4 & 0b00000010) bitmask |= 16;
  1295.                                         if (r5 & 0b00000001) bitmask |= 32;
  1296.                                         if (r6 & 0b10000000) bitmask |= 64;
  1297.                                         if (r7 & 0b01000000) bitmask |= 128;
  1298.                                         break;
  1299.                                 case 7:
  1300.                                         if ((7 >= dataPortPin) && (7 <= clockPortPin)) {
  1301.                                                 onMask |= 128;
  1302.                                                 r7 = array[c + (7-dataPortPin) * blockSize];
  1303.                                         }
  1304.  
  1305.                                         if (r0 & 0b01000000) bitmask |= 1;
  1306.                                         if (r1 & 0b00100000) bitmask |= 2;
  1307.                                         if (r2 & 0b00010000) bitmask |= 4;
  1308.                                         if (r3 & 0b00001000) bitmask |= 8;
  1309.                                         if (r4 & 0b00000100) bitmask |= 16;
  1310.                                         if (r5 & 0b00000010) bitmask |= 32;
  1311.                                         if (r6 & 0b00000001) bitmask |= 64;
  1312.                                         if (r7 & 0b10000000) bitmask |= 128;
  1313.                                         break;
  1314.                                 }
  1315.  
  1316.                         // Set  HIGH, set LOW  zeros, set LOW zeros and ones.
  1317.                         FAB_PORT(dataPortId, onMask);
  1318.                         DELAY_CYCLES(high0 - sbiCycles);
  1319.  
  1320.                         FAB_PORT(dataPortId, bitmask);
  1321.                         DELAY_CYCLES( high1 - high0 + sbiCycles);
  1322.  
  1323.                         FAB_PORT(dataPortId, 0x00);
  1324.                         // Estimate overhead of math above to ~ 20 cycles
  1325.                         DELAY_CYCLES(low0 - cbiCycles - 20);
  1326.                 }
  1327.         }
  1328. }
  1329.  
  1330.  
  1331. template<FAB_TDEF>
  1332. inline void
  1333. avrBitbangLedStrip<FAB_TVAR>::onePortSoftwareSendBytes(const uint16_t count, const uint8_t * array)
  1334. {
  1335.  
  1336.         for(uint16_t c=0; c < count; c++) {
  1337.                 const uint8_t val = array[c];
  1338.                 for(int8_t b=7; b>=0; b--) {
  1339.                         const bool bit = (val>>b) & 0x1;
  1340.  
  1341.                         if (bit) {
  1342.                                 // Send a ONE
  1343.  
  1344.                                 // HIGH with ASM sbi (2 words, 2 cycles)
  1345.                                 SET_PORT_HIGH(dataPortId, dataPortPin);
  1346.                                 // Wait exact number of cycles specified
  1347.                                 DELAY_CYCLES(high1 - sbiCycles);
  1348.                                 //  LOW with ASM cbi (2 words, 2 cycles)
  1349.                                 SET_PORT_LOW(dataPortId, dataPortPin);
  1350.                                 // Wait exact number of cycles specified
  1351.                                 DELAY_CYCLES(low1 - cbiCycles);
  1352.                         } else {
  1353.                                 // Send a ZERO
  1354.  
  1355.                                 // HIGH with ASM sbi (2 words, 2 cycles)
  1356.                                 SET_PORT_HIGH(dataPortId, dataPortPin);
  1357.                                 // Wait exact number of cycles specified
  1358.                                 DELAY_CYCLES(high0 - sbiCycles);
  1359.                                 //  LOW with ASM cbi (2 words, 2 cycles)
  1360.                                 SET_PORT_LOW(dataPortId, dataPortPin);
  1361.                                 // Wait exact number of cycles specified
  1362.                                 DELAY_CYCLES(low0 - cbiCycles);
  1363.                         }
  1364.                 }
  1365.         }
  1366. }
  1367.  
  1368.  
  1369. template<FAB_TDEF>
  1370. inline void
  1371. avrBitbangLedStrip<FAB_TVAR>::clear(const uint16_t numPixels)
  1372. {
  1373.         if (protocol == SPI_BITBANG) {
  1374.                 // SPI: Send start frame, Clean numPixels, and Reset LED strip
  1375.                 spiSoftwareSendFrame(1 + numPixels + (numPixels+1)/2, 0);
  1376.         } else {
  1377.                 // 1-wire: Delay next pixels to cause a refresh
  1378.                 const uint8_t array[4] = {0,0,0,0};
  1379.  
  1380.                 DISABLE_INTERRUPTS;
  1381.                 for( uint16_t i = 0; i < numPixels; i++) {
  1382.                         sendBytes(bytesPerPixel, array);
  1383.                 }
  1384.                 RESTORE_INTERRUPTS;
  1385.         }
  1386. }
  1387.  
  1388. template<FAB_TDEF>
  1389. inline void
  1390. avrBitbangLedStrip<FAB_TVAR>::grey(const uint16_t numPixels, const uint8_t value)
  1391. {
  1392.         const uint8_t array[4] = {value, value, value, value};
  1393.  
  1394.         DISABLE_INTERRUPTS;
  1395.         for( uint16_t i = 0; i < numPixels; i++) {
  1396.                 sendBytes(bytesPerPixel, array);
  1397.         }
  1398.         RESTORE_INTERRUPTS;
  1399. }
  1400.  
  1401. // 3B raw input array
  1402. template<FAB_TDEF>
  1403. inline void
  1404. avrBitbangLedStrip<FAB_TVAR>::sendPixels(
  1405.                 const uint16_t numPixels,
  1406.                 const uint8_t * array)
  1407. {
  1408.         DISABLE_INTERRUPTS;
  1409.         sendBytes(numPixels * bytesPerPixel, array);
  1410.         RESTORE_INTERRUPTS;
  1411. }
  1412.  
  1413.  
  1414. // Since colors is a constant, the switch case will convert to 4 sendBytes max.
  1415. #define SEND_REMAPPED_PIXELS(numPixels, array, sendWhite)          \
  1416.                 DISABLE_INTERRUPTS;                                \
  1417.                 for (uint16_t i = 0; i < numPixels; i++) {         \
  1418.                         switch (colors) {                          \
  1419.                                 case RGB:                          \
  1420.                                         sendBytes(1, &array[i].r); \
  1421.                                         sendBytes(1, &array[i].g); \
  1422.                                         sendBytes(1, &array[i].b); \
  1423.                                         break;                     \
  1424.                                 case GRB:                          \
  1425.                                         sendBytes(1, &array[i].g); \
  1426.                                         sendBytes(1, &array[i].r); \
  1427.                                         sendBytes(1, &array[i].b); \
  1428.                                         break;                     \
  1429.                                 case BGR:                          \
  1430.                                         sendBytes(1, &array[i].b); \
  1431.                                         sendBytes(1, &array[i].g); \
  1432.                                         sendBytes(1, &array[i].r); \
  1433.                                         break;                     \
  1434.                                 case RGBW:                         \
  1435.                                         sendBytes(1, &array[i].r); \
  1436.                                         sendBytes(1, &array[i].g); \
  1437.                                         sendBytes(1, &array[i].b); \
  1438.                                         sendWhite;                 \
  1439.                                         break;                     \
  1440.                                 case GRBW:                         \
  1441.                                         sendBytes(1, &array[i].g); \
  1442.                                         sendBytes(1, &array[i].r); \
  1443.                                         sendBytes(1, &array[i].b); \
  1444.                                         sendWhite;                 \
  1445.                                         break;                     \
  1446.                                 case HBGR:                         \
  1447.                                         sendWhite;                 \
  1448.                                         sendBytes(1, &array[i].b); \
  1449.                                         sendBytes(1, &array[i].g); \
  1450.                                         sendBytes(1, &array[i].r); \
  1451.                                         break;                     \
  1452.                                 default:                           \
  1453.                                         break;                     \
  1454.                         }                                          \
  1455.                 }                                                  \
  1456.                 RESTORE_INTERRUPTS;
  1457.  
  1458. #define sendWhiteMacro sendBytes(1, &array[i].w)
  1459. #define SEND_REMAPPED_PIXELS_4B(numPixels, array) SEND_REMAPPED_PIXELS(numPixels, array, sendWhiteMacro)
  1460. #define SEND_REMAPPED_PIXELS_3B(numPixels, array) SEND_REMAPPED_PIXELS(numPixels, array, )
  1461.  
  1462. // 4B struct input arrays
  1463. template<FAB_TDEF>
  1464. inline void
  1465. avrBitbangLedStrip<FAB_TVAR>::sendPixels(
  1466.                 const uint16_t numPixels,
  1467.                 const rgbw * array)
  1468. {
  1469.         if (colors == RGBW || colors == NONE) {
  1470.                 sendPixels(numPixels, (const uint8_t *) array);
  1471.         } else if (colors == RGB) {
  1472.                 // Output array is same order but 3B, send as 32bit, which will be converted
  1473.                 sendPixels(numPixels, (const uint32_t *) array);
  1474.         } else {
  1475.                 // Handle input array of different format than LED strip
  1476.                 SEND_REMAPPED_PIXELS_4B(numPixels, array);
  1477.         }
  1478. }
  1479.  
  1480. template<FAB_TDEF>
  1481. inline void
  1482. avrBitbangLedStrip<FAB_TVAR>::sendPixels(
  1483.                 const uint16_t numPixels,
  1484.                 const grbw * array)
  1485. {
  1486.         if (colors == GRBW || colors == NONE) {
  1487.                 sendPixels(numPixels, (const uint8_t *) array);
  1488.         } else if (colors == GRB) {
  1489.                 sendPixels(numPixels, (const uint32_t *) array);
  1490.         } else {
  1491.                 // Handle input array of different format than LED strip
  1492.                 SEND_REMAPPED_PIXELS_4B(numPixels, array);
  1493.         }
  1494. }
  1495.  
  1496. template<FAB_TDEF>
  1497. inline void
  1498. avrBitbangLedStrip<FAB_TVAR>::sendPixels(
  1499.                 const uint16_t numPixels,
  1500.                 const hbgr * array)
  1501. {
  1502.         if (colors == HBGR || colors == NONE) {
  1503.                 sendPixels(numPixels, (const uint8_t *) array);
  1504.         } else if (colors == BGR) {
  1505.                 sendPixels(numPixels, (const uint32_t *) array);
  1506.         } else {
  1507.                 // Handle input array of different format than LED strip
  1508.                 SEND_REMAPPED_PIXELS_4B(numPixels, array);
  1509.         }
  1510. }
  1511.  
  1512. // 3B struct input arrays
  1513. template<FAB_TDEF>
  1514. inline void
  1515. avrBitbangLedStrip<FAB_TVAR>::sendPixels(
  1516.                 const uint16_t numPixels,
  1517.                 const rgb * array)
  1518. {
  1519.         if (colors == RGB || colors == NONE) {
  1520.                 // Input array is native format. No conversion.
  1521.                 sendPixels(numPixels, (const uint8_t *) array);
  1522.         } else {
  1523.                 // 4B, or 3B pixel array with different byte order, must be converted.
  1524.                 SEND_REMAPPED_PIXELS_3B(numPixels, array);
  1525.         }
  1526. }
  1527.  
  1528. template<FAB_TDEF>
  1529. inline void
  1530. avrBitbangLedStrip<FAB_TVAR>::sendPixels(
  1531.                 const uint16_t numPixels,
  1532.                 const grb * array)
  1533. {
  1534.         if (colors == GRB || colors == NONE) {
  1535.                 sendPixels(numPixels, (const uint8_t *) array);
  1536.         } else {
  1537.                 SEND_REMAPPED_PIXELS_3B(numPixels, array);
  1538.         }
  1539. }
  1540.  
  1541. template<FAB_TDEF>
  1542. inline void
  1543. avrBitbangLedStrip<FAB_TVAR>::sendPixels(
  1544.                 const uint16_t numPixels,
  1545.                 const bgr * array)
  1546. {
  1547.         if (colors == BGR || colors == NONE) {
  1548.                 sendPixels(numPixels, (const uint8_t *) array);
  1549.         } else {
  1550.                 SEND_REMAPPED_PIXELS_3B(numPixels, array);
  1551.         }
  1552. }
  1553.  
  1554. // 4B raw input array
  1555. template<FAB_TDEF>
  1556. inline void
  1557. avrBitbangLedStrip<FAB_TVAR>::sendPixels(
  1558.                 const uint16_t numPixels,
  1559.                 const uint32_t * pixelArray)
  1560. {
  1561.         DISABLE_INTERRUPTS;
  1562.  
  1563.         if (colors >= PIXEL_FORMAT_4B) {
  1564.                 // 4 byte per pixel array, send  bytes.
  1565.                 sendBytes((const uint16_t) numPixels * bytesPerPixel, (const uint8_t *) pixelArray);
  1566.         } else {
  1567.                 // 3 byte per pixel array, send 3 out of 4 bytes.
  1568.                 for (int i=0; i< numPixels; i++) {
  1569.                         uint8_t * bytes = (uint8_t *) & pixelArray[i];
  1570.                         // For LED strips using 3 bytes per color, drop a byte.
  1571.                         sendBytes(bytesPerPixel, bytes);
  1572.                 }
  1573.         }
  1574.  
  1575.         RESTORE_INTERRUPTS;
  1576. }
  1577.  
  1578. // Palette input arrays
  1579. template<FAB_TDEF>
  1580. template <const uint8_t bitsPerPixel, class T>
  1581. inline void
  1582. avrBitbangLedStrip<FAB_TVAR>::sendPixels (
  1583.                 const uint16_t count,
  1584.                 const uint8_t * pixelArray,
  1585.                 const uint8_t * reds,
  1586.                 const uint8_t * greens,
  1587.                 const uint8_t * blues)
  1588. {
  1589.         // Debug: Support simple palettes 2, 4, 16 or 256 colors
  1590.  
  1591.         STATIC_ASSERT( bitsPerPixel == 1 || bitsPerPixel == 2 ||
  1592.                  bitsPerPixel == 4 || bitsPerPixel == 8,
  1593.                 Unsupported_palette_size);
  1594.  
  1595.         // 1,2 4 and 8 bit bitmasks. Note 3,5,6 don't make sense
  1596.         // and 5bits is handled separately with uint16_t type.
  1597.         const uint8_t andMask = (bitsPerPixel ==1) ? 0x01 :
  1598.                         (bitsPerPixel == 2) ? 0x03 :
  1599.                         (bitsPerPixel == 4) ? 0x0F :
  1600.                         (bitsPerPixel == 8) ? 0xFF :
  1601.                         0x00;
  1602.  
  1603.         DISABLE_INTERRUPTS;
  1604.  
  1605.         // Send each byte as 1 to 4 pixels
  1606.         uint16_t offset;
  1607.         offset = 0;
  1608.         uint16_t index;
  1609.         index = 0;
  1610.         while (1) {
  1611.                 uint8_t elem;
  1612.                 elem = pixelArray[offset++];
  1613.                 for (uint8_t j = 0; j < 8/bitsPerPixel; j++) {
  1614.                         if (index++ >= count) {
  1615.                                 goto end;
  1616.                         }
  1617.                         const uint8_t colorIndex = elem & andMask;
  1618.                         T pixel;
  1619.                         pixel.r = reds[colorIndex];
  1620.                         pixel.g = greens[colorIndex];
  1621.                         pixel.b = blues[colorIndex];
  1622.                         // @note support w in future
  1623.                         sendPixels(1, &pixel);
  1624.                         elem >>= bitsPerPixel;
  1625.                 }
  1626.         }
  1627. end:
  1628.         RESTORE_INTERRUPTS;
  1629. }
  1630.  
  1631. // Palette input arrays
  1632. template<FAB_TDEF>
  1633. template <const uint8_t bitsPerPixel>
  1634. inline void
  1635. avrBitbangLedStrip<FAB_TVAR>::sendPixels (
  1636.                 const uint16_t count,
  1637.                 const uint8_t * pixelArray,
  1638.                 const uint8_t * palette)
  1639. {
  1640.         // Debug: Support simple palettes 2, 4, 16 or 256 colors
  1641.         STATIC_ASSERT( bitsPerPixel == 1 || bitsPerPixel == 2 ||
  1642.                  bitsPerPixel == 4 || bitsPerPixel == 8,
  1643.                 Unsupported_palette_size);
  1644.  
  1645.         // 1,2 4 and 8 bit bitmasks. Note 3,5,6 don't make sense
  1646.         // and 5bits is handled separately with uint16_t type.
  1647.         const uint8_t andMask = (bitsPerPixel ==1) ? 0x01 :
  1648.                         (bitsPerPixel == 2) ? 0x03 :
  1649.                         (bitsPerPixel == 4) ? 0x0F :
  1650.                         (bitsPerPixel == 8) ? 0xFF :
  1651.                         0x00;
  1652.  
  1653.         DISABLE_INTERRUPTS;
  1654.  
  1655.         // Send each byte as 1 to 4 pixels
  1656.         uint16_t offset;
  1657.         offset = 0;
  1658.         uint16_t index;
  1659.         index = 0;
  1660.         while (1) {
  1661.                 uint8_t elem;
  1662.                 elem = pixelArray[offset++];
  1663.                 for (uint8_t j = 0; j < 8/bitsPerPixel; j++) {
  1664.                         if (index++ >= count) {
  1665.                                 goto end;
  1666.                         }
  1667.                         const uint8_t colorIndex = elem & andMask;
  1668.                         sendBytes(bytesPerPixel, &palette[bytesPerPixel*colorIndex]);
  1669.                         elem >>= bitsPerPixel;
  1670.                 }
  1671.         }
  1672. end:
  1673.         RESTORE_INTERRUPTS;
  1674. }
  1675.  
  1676. template<FAB_TDEF>
  1677. template <const uint8_t bitsPerPixel, class T>
  1678. inline void
  1679. avrBitbangLedStrip<FAB_TVAR>::sendPixels (
  1680.                 const uint16_t count,
  1681.                 const uint8_t * pixelArray,
  1682.                 const T * palette)
  1683. {
  1684.         // Debug: Support simple palettes 2, 4, 16 or 256 colors
  1685.         STATIC_ASSERT( bitsPerPixel == 1 || bitsPerPixel == 2 ||
  1686.                 bitsPerPixel == 4 || bitsPerPixel == 8,
  1687.                 Unsupported_palette_size);
  1688.  
  1689.         // 1,2 4 and 8 bit bitmasks. Note 3,5,6 don't make sense
  1690.         // and 5bits is handled separately with uint16_t type.
  1691.         const uint8_t andMask = (bitsPerPixel ==1) ? 0x01 :
  1692.                         (bitsPerPixel == 2) ? 0x03 :
  1693.                         (bitsPerPixel == 4) ? 0x0F :
  1694.                         (bitsPerPixel == 8) ? 0xFF :
  1695.                         0x00;
  1696.  
  1697.         DISABLE_INTERRUPTS;
  1698.  
  1699.         // Send each byte as 1 to 4 pixels
  1700.         uint16_t offset;
  1701.         offset = 0;
  1702.         uint16_t index;
  1703.         index = 0;
  1704.         while (1) {
  1705.                 uint8_t elem;
  1706.                 elem = pixelArray[offset++];
  1707.                 for (uint8_t j = 0; j < 8/bitsPerPixel; j++) {
  1708.                         if (index++ >= count) {
  1709.                                 goto end;
  1710.                         }
  1711.                         const uint8_t colorIndex = elem & andMask;
  1712.                         sendBytes(bytesPerPixel, &palette[bytesPerPixel*colorIndex]);
  1713.                         elem >>= bitsPerPixel;
  1714.                 }
  1715.         }
  1716. end:
  1717.         RESTORE_INTERRUPTS;
  1718. }
  1719.  
  1720. template<FAB_TDEF>
  1721. template <class pixelType>
  1722. inline void
  1723. avrBitbangLedStrip<FAB_TVAR>::sendPixelsRemap(
  1724.                 const uint16_t numPixels,
  1725.                 const uint16_t * pixelMap,
  1726.                 const pixelType * array)
  1727. {
  1728.         // The uint8_t raw type actuy does not hold the whole pixel, it needs 3 bytes.
  1729.         const uint16_t size = (sizeof(pixelType) == 1) ? bytesPerPixel : 1;
  1730.  
  1731.         DISABLE_INTERRUPTS;
  1732.         for (uint16_t i = 0; i < numPixels; i += 1) {
  1733.                 const uint16_t ri = pixelMap[i];
  1734.                 sendPixels((uint16_t) 1, &array[size * ri]);
  1735.         }
  1736.         RESTORE_INTERRUPTS;
  1737. }
  1738.  
  1739. // @note The 8bit per pixel works but 2bits per pixel does not at 16MHz.
  1740. template<FAB_TDEF>
  1741. template <const uint8_t bitsPerPixel, class pixelType>
  1742. inline void
  1743. avrBitbangLedStrip<FAB_TVAR>::sendPixelsRemap (
  1744.                 const uint16_t numPixels,
  1745.                 const uint16_t * pixelMap,
  1746.                 const uint8_t * pixelArray,
  1747.                 const pixelType * palette)
  1748. {
  1749.         // Support only palettes with 2, 4, 16 or 256 colors
  1750.         STATIC_ASSERT( bitsPerPixel == 1 || bitsPerPixel == 2 ||
  1751.                 bitsPerPixel == 4 || bitsPerPixel == 8,
  1752.                 Unsupported_palette_size);
  1753.  
  1754.         const uint16_t size = (sizeof(pixelType) == 1) ? bytesPerPixel : 1;
  1755.  
  1756.         DISABLE_INTERRUPTS;
  1757.         for (uint16_t i = 0; i < numPixels; i++) {
  1758.                 // Remapped i: index in array of the next pixel to push.
  1759.                 const uint16_t ri = pixelMap[i];
  1760.                 // Extract color index via bitmasks
  1761.                 const uint8_t colorIndex = GET_PIXEL(pixelArray, ri, bitsPerPixel);
  1762.                 // Get the color/pixel to send
  1763.                 const pixelType * pixel =  &palette[size * colorIndex];
  1764.                 sendPixels(1, pixel);
  1765.         }
  1766.         RESTORE_INTERRUPTS;
  1767. }
  1768.  
  1769.  
  1770. template<FAB_TDEF>
  1771. template <const uint8_t bitsPerPixel, class pixelType>
  1772. inline void
  1773. avrBitbangLedStrip<FAB_TVAR>::sendPixelsRemap (
  1774.                 const uint8_t numPixels,
  1775.                 const uint8_t * pixelMap,
  1776.                 const uint8_t * pixelArray,
  1777.                 const pixelType * palette)
  1778. {
  1779.         // Support only palettes with 2, 4, 16 or 256 colors
  1780.         STATIC_ASSERT( bitsPerPixel == 1 || bitsPerPixel == 2 ||
  1781.                 bitsPerPixel == 4 || bitsPerPixel == 8,
  1782.                 Unsupported_palette_size);
  1783.  
  1784.         const uint16_t size = (sizeof(pixelType) == 1) ? bytesPerPixel : 1;
  1785.  
  1786.         DISABLE_INTERRUPTS;
  1787.         for (uint8_t i = 0; i < numPixels; i++) {
  1788.                 // Remapped i: index in array of the next pixel to push.
  1789.                 const uint8_t ri = pixelMap[i];
  1790.                 // Extract color index via bitmasks
  1791.                 const uint8_t colorIndex = GET_PIXEL(pixelArray, ri, bitsPerPixel);
  1792.                 // Get the color/pixel to send
  1793.                 const pixelType * pixel =  &palette[size * colorIndex];
  1794.                 sendPixels(1, pixel);
  1795.         }
  1796.         RESTORE_INTERRUPTS;
  1797. }
  1798.  
  1799.  
  1800. /// @todo Rewrite this to support R5G6B5, R4G4B4W4 and a variable brightness.
  1801. template<FAB_TDEF>
  1802. template <uint8_t brightness>
  1803. inline void
  1804. avrBitbangLedStrip<FAB_TVAR>::sendPixels(
  1805.                 int count,
  1806.                 uint16_t * pixelArray)
  1807. {
  1808.         const uint8_t mask5 = ((1 << (5 - brightness))-1) || ((1 << brightness) - 1);
  1809.         const uint8_t mask10 = ((1 << (10 - brightness))-1) || ((1 << brightness) - 1);
  1810.         uint8_t bytes[4];
  1811.  
  1812.         // Debug: Support brightness 0..3
  1813.         STATIC_ASSERT(brightness < 3, Unsupported_brightness_level);
  1814.  
  1815.         DISABLE_INTERRUPTS;
  1816.  
  1817.         bytes[3] = 0;
  1818.         for (int i = 0; i < count; i++) {
  1819.                 const uint16_t elem = pixelArray[i];
  1820.                 bytes[0] = (uint8_t) elem << brightness;
  1821.                 bytes[1] = (elem >> (5 - brightness)) & mask5;
  1822.                 bytes[2] = (elem >> (10 - brightness)) & mask10;
  1823.                 sendBytes(bytesPerPixel, bytes);
  1824.         }
  1825.  
  1826.         RESTORE_INTERRUPTS;
  1827. }
  1828.  
  1829.  
  1830.  
  1831. ////////////////////////////////////////////////////////////////////////////////
  1832. // Implementation classes for LED strip
  1833. // Defines the actual LED timings
  1834. // WS2811 2811B 2812B 2812S 2801 LEDs use similar protocols and timings
  1835. ////////////////////////////////////////////////////////////////////////////////
  1836.  
  1837.  
  1838. ////////////////////////////////////////////////////////////////////////////////
  1839. // WS2812B (default, mainstream)
  1840. ////////////////////////////////////////////////////////////////////////////////
  1841. #if 0
  1842. // These are the less agressive bitbanging timings
  1843. #define WS2812B_1H_CY CYCLES(650)  // 650ns-950ns _----------__
  1844. #define WS2812B_1L_CY CYCLES(125)  // 250ns-550ns .    .    .
  1845. #define WS2812B_0H_CY CYCLES(125)  // 250ns-550ns _-----_______
  1846. #define WS2812B_0L_CY CYCLES(650)  // 650ns-950ns .    .    .
  1847. #define WS2812B_MS_REFRESH 50      // 50,000ns Minimum sleep time to reset LED strip
  1848. #define WS2812B_NS_RF 2000000      // Max refresh rate for  pixels to light up 2msec (LED PWM is 500Hz)
  1849. #else
  1850. // These are the more agressive bitbanging timings, note 0 and 1 have different durations
  1851. #define WS2812B_1H_CY CYCLES(500)  // 6  7 10 _----------__
  1852. #define WS2812B_1L_CY CYCLES(125)  // 2  2  4 .    .    .
  1853. #define WS2812B_0H_CY CYCLES(125)  // 2  2  5 _-----_______
  1854. #define WS2812B_0L_CY CYCLES(188)  // 2  2  7 .    .    .
  1855. #define WS2812B_MS_REFRESH 20      // Minimum sleep time (low) to reset LED strip
  1856. #define WS2812B_NS_RF 2000000      // Max refresh rate for  pixels to light up 2msec (LED PWM is 500Hz)
  1857. #endif
  1858.  
  1859. #define FAB_TVAR_WS2812B WS2812B_1H_CY, WS2812B_1L_CY, WS2812B_0H_CY, \
  1860.         WS2812B_0L_CY, WS2812B_MS_REFRESH, dataPortId, dataPortBit, A, 0, GRB, ONE_PORT_BITBANG
  1861. template<avrLedStripPort dataPortId, uint8_t dataPortBit>
  1862. class ws2812b : public avrBitbangLedStrip<FAB_TVAR_WS2812B>
  1863. {
  1864.         public:
  1865.         ws2812b() : avrBitbangLedStrip<FAB_TVAR_WS2812B>() {};
  1866.         ~ws2812b() {};
  1867. };
  1868. #undef FAB_TVAR_WS2812B
  1869.  
  1870.  
  1871. ////////////////////////////////////////////////////////////////////////////////
  1872. // WS2812BS - Bitbang the pixels to two ports in parel.
  1873. // The pixel array is split in two. Each port displays a half.
  1874. ////////////////////////////////////////////////////////////////////////////////
  1875. #define FAB_TVAR_WS2812BS WS2812B_1H_CY, WS2812B_1L_CY, WS2812B_0H_CY, \
  1876.         WS2812B_0L_CY, WS2812B_MS_REFRESH, dataPortId1, dataPortBit1, dataPortId2, dataPortBit2, GRB, TWO_PORT_SPLIT_BITBANG
  1877. template<avrLedStripPort dataPortId1, uint8_t dataPortBit1,avrLedStripPort dataPortId2, uint8_t dataPortBit2>
  1878. class ws2812bs : public avrBitbangLedStrip<FAB_TVAR_WS2812BS>
  1879. {
  1880.         public:
  1881.         ws2812bs() : avrBitbangLedStrip<FAB_TVAR_WS2812BS>() {};
  1882.         ~ws2812bs() {};
  1883. };
  1884. #undef FAB_TVAR_WS2812BS
  1885.  
  1886. ////////////////////////////////////////////////////////////////////////////////
  1887. // WS2812B8S - Bitbang the pixels to eight ports in parel.
  1888. // The pixel array is split in 8. Each port displays a portion.
  1889. /////////
A hozzászólás módosítva: Okt 30, 2016

LEDszalag.jpg
    
(#) kapu48 válasza szikorapéter hozzászólására (») Okt 30, 2016 /
 
(#) dannu hozzászólása Okt 30, 2016 /
 
Sziasztok !
Szeretnék építeni horgászati célból egy víz mélység mérőt . Valaki csinált már valaki ilyet ?
Vagy valami project is jó aki épített már ilyet. Kerestem a googliba de csak olyat találtam ami vizes palack szintjét méri.
(#) proba válasza szikorapéter hozzászólására (») Okt 30, 2016 /
 
Mondjuk a Vpp lábra a linkelt rajzon is 13V ot köt. A régi ablakos epromok is így voltak írhatóak. Úgy emlékszem a régiek egy kaptafára készültek, apró eltérésekkel. ( pl 12V/12,5/13V égetési feszültség) De a legtöbbnél a katalógus oldalon pontos égetési idődiagramot találsz. Az 5V osak talán a mai modern flash alapúak lehetnek. Azok meg lehet már más időzítést igényelnek.
(#) proba válasza dannu hozzászólására (») Okt 30, 2016 /
 
Ultrahangos távolságmérő esetleg?
(#) szikorapéter válasza proba hozzászólására (») Okt 30, 2016 /
 
Az 5V-os égető feszültségűt lényegében az arduino-val is képes vagyok írni?
(#) Bakman válasza proba hozzászólására (») Okt 30, 2016 /
 
Víz alatt nem működik.
(#) Massawa hozzászólása Okt 30, 2016 /
 
Sziasztok

A fiamnak szeretnék segiteni, de nekem sajnos nem sok ismeretem van az Arduino nyelvéröl.
Egy 1602-s LCD-t akar életre kelteni I2C kommunikácion keresztül.

Mindent bemásolt, de mint kiderült az I2C meghajtok nem egészen egyformák. Az öve a képen láthato modon van bekötve ( csak a PCFchipröl meg az LCD-röl van szo.

a kodban van egy ilyen sor:

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

Itt a 0x27 a cim, de mit jelentenek a számok? - szerintem a portok, de nem vagyok biztos.

Tény, hogy a portok igy vannak:

P0 - Rs
P1 - RW
P2 - EN
P3 - BL
P4 - D4
P5 - D5
P6 - D6
P7 - D7
Tudna valaki segiteni? Kösz!

I2C LCD
A hozzászólás módosítva: Okt 30, 2016
(#) Massawa válasza Massawa hozzászólására (») Okt 30, 2016 /
 
Közben már sikerült kideriteni, hogy mik a számok:

(Addr, EN, RW, RS, D4, D5, D6, D7, BL, BLPOL)

Sajnos még igy sem megy....

Azt linket ( meg mást is) már többször végigrágta, de még minding nincs semmi az LCD-n.
A hozzászólás módosítva: Okt 30, 2016
(#) kapu48 válasza Massawa hozzászólására (») Okt 30, 2016 1 /
 
A cimző átkötések (A0,A1,A2) szabadok?
(#) pjg válasza Massawa hozzászólására (») Okt 30, 2016 /
 
A kontraszt szabályzó potméter be van állítva?
(#) Massawa válasza kapu48 hozzászólására (») Okt 31, 2016 /
 
Igen a válasz mind a kettöre.
(#) (Felhasználó 120038) válasza Massawa hozzászólására (») Okt 31, 2016 /
 
Szia!

Mert nem így kell sokesetben. Ha I2C -n keresztül megy akkor az illesztő már rá van kötve/forrasztva az LCD-re. Az illesztő pedig az Arduino-ra, 4 db vezetékkel, amiből egy a GND, egy meg a táp 5V, a többi pedig az adatoknak. (SCL-> A5, SDA-> A4 lábakra, legalábbis Nanon.)

Akkor minek ennyi láb a

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

definiálásakor?

Első lépés:

Töltsön fel egy kis I2C adress monitor programot, mikor a kör készen van. Az megmondja a pontos címét az illezstőnek. (0X27, vagy valami más)

Ha ez megvan akkor:

  1. #include <LiquidCrystal_I2C.h>
  2. LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x20 for a 16 chars and 2 line display
  3.  
  4. oid setup() {
  5.   // initialize serial communication:
  6.     lcd.init();                  
  7.  
  8.   // Print a message to the LCD.
  9.   lcd.backlight();
  10.   lcd.print("Hello!");
  11.   lcd.setCursor(0, 1);
  12.   delay(1000);
  13.  
  14. }



Azt elfelejtettem, hogy ehhez lehet másik LCD lib kell. Ha gond van akkor elküldhetek egyet, de ahonnan beszerezte, le is tud tölteni egyet. Sok esetben a lib-ben vannak példák.
A hozzászólás módosítva: Okt 31, 2016
(#) Massawa válasza (Felhasználó 120038) hozzászólására (») Okt 31, 2016 /
 
Kösz, majd megnézzük. Pontosan az a baj, hogy van egy sereg I2C könyvtár és én sajnos nem tudom mi a különbség közöttük igy azt sem mikor melyik lenne a jo.
Azt a sort viszont fontosnak találom, mert pontosan ott van specifikálva, hogy hogyan van az I2c illesztve az LCD-hez.
A te 2. Sorodban m´ar csak az van fixelve higy milyen a display (1602) de az nincs, hogy hogyan vannak az I2C modulhoz illesztve az LCD lábai (RS, EN RW stb)
Ahogy tegnap körülnéztem szinte mindegyik máshogy van az LCD hez kötve igy ennek látom az értelmét. A cimet még ki kell keresni ( habár a 0x27 van ráirva - az egyetlen adat. )
(#) (Felhasználó 120038) válasza (Felhasználó 120038) hozzászólására (») Okt 31, 2016 /
 
Az I2C illesztő áramkörhöz más lib kell. Ez az áramkör elintéz mindent ami kell, így csak a cím, és a SCL SDA lábak lesznek foglaltak az Arduino-n.

Ha jól megnézed akkor amit küldtél sok láb között szerepelt:
D4, D5, D6, D7, ami a 4 bites kommunkiációs bekötéshez jó. (Az LCD tudna 8 biteset is, van azon vagy 16 láb, ha jól emlékszem)

Az I2C illesztő áramkör nélkül is be lehet kötni az LCD-t az arduinoba, csak akkor SOK láb kell, a sima kommunikációhoz, a háttérvilágítás ki be kapcsolásához, EN és RW engedélyezéséhez, tiltásához stb.
(#) (Felhasználó 120038) válasza Massawa hozzászólására (») Okt 31, 2016 /
 
Idézet:
„A te 2. Sorodban m´ar csak az van fixelve higy milyen a display (1602) de az nincs, hogy hogyan vannak az I2C modulhoz illesztve az LCD lábai (RS, EN RW stb)”


Igen.

Nem tudom honnan szereztétek be a dolgokat, de én CHINA városból, ott így megy... Volt LCD-m, ami külön jött az illesztővel, ráforrasztottam, és ment így, valamint volt ami már eleve így összerakva jött, az is így ment.

Más:

Ha az LCD és az illesztő külön jött, akkor elképzelhető, hogy fordítva lett bekötve!!!! Két fajta I2C illesztő van ugyanonnan! Van az egyik lábnál ( az I2C illesztőn) egy négyzet, az az első! (RÉGEN VOLT NEM 100, nézzetek utána.) Nem tudom Ti honnan szereztétek, nálam ilyen is volt.
A hozzászólás módosítva: Okt 31, 2016
(#) (Felhasználó 120038) válasza (Felhasználó 120038) hozzászólására (») Okt 31, 2016 /
 
Idézet az én LCD libemből (LiquidCrystal_I2C.h):

  1. class LiquidCrystal_I2C : public Print {
  2. public:
  3.   LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows);
  4.   void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS );
  5.   void clear();
  6.   void home();
  7.   void noDisplay();
  8.   void display();
  9.   void noBlink();
  10.   void blink();
  11.   void noCursor();
  12. .
  13. .
  14. .
  15. .
  16. stb.


Itt csak ennyi kell.

Csatoltam a nálam működő Lib-et.
(#) Massawa válasza (Felhasználó 120038) hozzászólására (») Okt 31, 2016 /
 
Mi is onnan vettük, most 3 olyan 1602-vel (BLUE) kisérletezik amin már rá van forrasztva az I2C modul, azt mértem ki biztos ami biztos alapon. Igy legalább az tisztázott hogyan van bekötve. Na majd ha elökerül, akkor mindjárt nekiül.
(#) (Felhasználó 120038) válasza (Felhasználó 120038) hozzászólására (») Okt 31, 2016 /
 
Most látom, hogy az enyémben is benne vannak ezek az értékek, de bele vannak drótozva a programba. Lehet őket állítgatni, más értéket adni neki, de úgy látszik, hogy ehhez az I2C illeszőkhöz nem kell...

  1. #define En B00000100  // Enable bit     Ezeket lehetne változtatgatni, de nem kellett nálam
  2. #define Rw B00000010  // Read/Write bit
  3. #define Rs B00000001  // Register select bit
  4.  
  5. class LiquidCrystal_I2C : public Print {
  6. public:
  7.   LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows); //Látszik, hogy csak címet, oszlopot és sort kér csak
  8.  
  9.  
  10. //mikor Arduino- programban kiadod az LCD.begin(); utasítást, akkor az ezekkel a paraméterekkel fog futni! 5*8 pont, sor/oszlop, de csak akkor, ha a begin(); zárójelek közötti rész üres.
  11.  
  12. void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS );
  13.  
  14.  
  15.   void clear();
  16.   void home();
  17.   void noDisplay();
  18.   void display();
  19.   void noBlink();
  20.   void blink();


Szóval ennél a lib-nél (vagy amit használsz ehhez az illesztőhöz) nem kell feltétlenül az a sok láb megadása. Egyszerűen nyissátok meg ezt a LiquidCrystal_I2C.h fájlt és nézzétek meg, milyen változókat kér.
A hozzászólás módosítva: Okt 31, 2016
Következő: »»   285 / 864
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem