არდუინო განათების გაყვანილობის დიაგრამა. შემობრუნების სიგნალების გაშვება WS2812 ფირზე და Arduino-ზე

ამ ტუტორიალში ჩვენ გავაგრძელებთ LED-ებთან მუშაობას, მაგრამ LED-ების რაოდენობას გავზრდით 5-მდე. და გავაკეთებთ გაშვებული ცეცხლის ეფექტს. LED-ების გასაკონტროლებლად, ჩვენ გამოვიყენებთ Arduino პორტის მანიპულირებას. ჩვენ პირდაპირ დავწერთ მონაცემებს Arduino პორტებში. ეს უკეთესია, ვიდრე კონკრეტული კონტროლერის შეყვანის/გამოსვლების მუშაობა. ეს საშუალებას მოგცემთ დააყენოთ LED- ების მნიშვნელობები ერთი მოქმედებით.

Arduino UNO-ს აქვს 3 პორტი:
B (ციფრული I/Os 8-დან 13-მდე)
C (ანალოგური შეყვანა)
D (ციფრული I/O 0-დან 7-მდე)

თითოეულ პორტს აკონტროლებს 3 რეგისტრი. რეგისტრაცია DDRგანსაზღვრავს რა ფეხი (პინი) იქნება შემავალი ან გამომავალი. დახმარებით რეგისტრაცია PORTშეგიძლიათ დააყენოთ პინი HIGH ან LOW. დახმარებით PIN-ის რეგისტრაციათქვენ შეგიძლიათ წაიკითხოთ Arduino ფეხების მდგომარეობა, როდესაც ისინი შეყვანილია.

ჩვენ გამოვიყენებთ B პორტს. პირველ რიგში, ჩვენ უნდა დავაყენოთ B პორტის ყველა პინი ციფრულ გამოსავალებად. პორტს B აქვს მხოლოდ 6 პინი. რეგისტრის ბიტები DDRB B პორტისთვის უნდა დაყენდეს 1-ზე, თუ ფეხი უნდა იქნას გამოყენებული როგორც OUTPUT, და 0-ზე, თუ ფეხი გამოყენებული იქნება როგორც INPUT. პორტის ბიტები დანომრილია 0-დან 7-მდე, მაგრამ ყოველთვის არ შეიცავს რვა ფეხს. მაგალითი:
DDRB = B00111110; // დააყენეთ პორტი B ქინძისთავები 1-დან 5-მდე, როგორც გამოსავლები და 0, როგორც შესასვლელი.

გთხოვთ გაითვალისწინოთ, რომ Microchip მიკროკონტროლერებში პირიქითაა. 0 ბიტი - ფეხი მუშაობს როგორც გამომავალი, ხოლო 1 - როგორც შემავალი.

ჩვენს გაშვებულ ხანძარსაწინააღმდეგო პროექტში ჩვენ გამოვიყენებთ 5 გასასვლელს:
DDRB = B00011111; // დააყენეთ პორტი B ქინძისთავები 0-დან 4-მდე გამოსავლებად

B პორტში მნიშვნელობების ჩასაწერად, თქვენ უნდა გამოიყენოთ PORTB რეგისტრი. შეგიძლიათ აანთოთ პირველი LED ბრძანებით:
PORTB=B00000001;
პირველი და მეოთხე:
PORTB=B00001001;

ახლა ხედავთ, რამდენად მარტივად შეგვიძლია LED-ების ჩართვა და გამორთვა. ახლა მოდით ვისაუბროთ ცვლის ოპერატორებზე

არსებობს 2 ორობითი shift ოპერატორი: მარცხენა shift ოპერატორი >. მარცხენა Shift ოპერატორი > ანაცვლებს ბიტებს მარჯვნივ.

მაგალითი:
varA = 1; // 00000001
varA = 1 varA = 1 varA = 1

ახლა დავუბრუნდეთ ჩვენს პროგრამას, რომელიც ნაჩვენებია ქვემოთ. ჩვენ უნდა შემოვიტანოთ 2 ცვლადი: პირველი ზევით ქვემოთშეიცავს მნიშვნელობას, სადაც გადაადგილება - ზემოთ ან ქვემოთ, და მეორე ცილონირა LED-ები ანათებს.

ფუნქციაში აწყობა()ჩვენ განვსაზღვრავთ, რომელი ფეხები უნდა იმუშაოს გამოსავლებად.

მთავარ მარყუჟის() პროგრამაში LED-ები სათითაოდ ანათებენ ცილონური ცვლადის გაზრდით და როდესაც ის მიაღწევს ყველაზე მაღალს, upDown ცვლადი დაყენებულია 0-ზე და LED-ები რიგრიგობით ანათებენ.

/* გაშვებული ცეცხლი. 5 LED */ ხელმოუწერელი char upDown=1; // დაწყება ზევით unsigned char cylon=0; // განსაზღვრავს LED-ის რიგის void setup() ( DDRB = B00011111; // დააყენეთ პორტი B 0-დან 4-მდე გამოსავალებად ) void loop() ( if(upDown==1)( // თუ ავდივართ ზემოთ, მაშინ cylon++; თუ ( cylon>=4) upDown=0; // როდესაც მიიღწევა ყველაზე მაღალი LED რიცხვი, შემდეგ შემდეგ ციკლში გადადით ქვემოთ) სხვა (cylon--; if(cylon==0) upDown=1; // როდესაც ყველაზე დაბალი მიიღწევა LED ნომერი, შემდეგ ციკლში ავდივართ ზემოთ) PORTB = 1

ამ ექსპერიმენტში ჩვენ ვაკეთებთ შუქს LED მასშტაბის გასწვრივ.

ნაწილების სია ექსპერიმენტისთვის

- 1 Arduino Uno დაფა;

- 1 პურის დაფა;

- 1 LED სასწორი;

- 10 რეზისტორი ნომინალური მნიშვნელობით 220 Ohm;

- 11 მამრობითი მამრობითი მავთული.

ძირითადი დიაგრამა

დიაგრამა პურის დაფაზე

ესკიზი

ჩამოტვირთეთ ესკიზი Arduino IDE-სთვის
// LED მასშტაბი დაკავშირებულია ქინძისთავების ჯგუფთან, რომელიც მდებარეობს // ზედიზედ. პირველი და ბოლო პინებისთვის მეგობრული სახელების მიცემა #define FIRST_LED_PIN 2 #define LAST_LED_PIN 11 void setup() ( // მასშტაბში არის 10 LED. ჩვენ შეგვიძლია დავწეროთ pinMode 10 // ჯერ: თითოეული პინისთვის, მაგრამ ეს იქნება bloat კოდი და // უფრო პრობლემური გახადა მისი შეცვლა. // ამიტომ უმჯობესია გამოვიყენოთ ციკლი. ჩვენ ვასრულებთ // pinMode (ინგლ. for) თითოეული პინისთვის (pin variable) // პირველიდან (= FIRST_LED_PIN) ბოლო ჩათვლით // (<= LAST_LED_PIN), всякий раз продвигаясь к следующему // (++pin увеличивает значение pin на единицу) // Так все пины от 2-го по 11-й друг за другом станут выходами for (int pin = FIRST_LED_PIN; pin <= LAST_LED_PIN; ++pin) pinMode(pin, OUTPUT); } void loop() { // получаем время в миллисекундах, прошедшее с момента // включения микроконтроллера unsigned int ms = millis(); // нехитрой арифметикой вычисляем, какой светодиод // должен гореть именно сейчас. Смена будет происходить // каждые 120 миллисекунд. Y % X — это остаток от // деления Y на X; плюс, минус, скобки — как в алгебре. int pin = FIRST_LED_PIN + (ms / 120) % 10; // включаем нужный светодиод на 10 миллисекунд, затем — // выключаем. На следующем проходе цикла он снова включится, // если гореть его черёд, и мы вообще не заметим отключения digitalWrite(pin, HIGH); delay(10); digitalWrite(pin, LOW); }

კოდის განმარტებები

  • გამოხატვის გამოყენება ამისთვისვაწყობთ მარყუჟი მრიცხველით . ამ შემთხვევაში, პორტების კონფიგურაცია გამოსავალისთვის. ასეთი ციკლის შესაქმნელად დაგჭირდებათ:
    • მრიცხველის ცვლადის ინიცირება მისი საწყისი მნიშვნელობით. ჩვენს შემთხვევაში: int pin = FIRST_LED_ PIN ;
    • მიუთითეთ მდგომარეობა, სანამ მარყუჟი მეორდება. ჩვენს შემთხვევაში: ქინძისთავი<= LAST_LED_ PIN ;
    • დაადგინეთ წესი, რომლითაც მრიცხველი შეიცვლება. ჩვენს შემთხვევაში ++ pin(იხილეთ ქვემოთ ოპერატორი ++ ).
  • მაგალითად, შეგიძლიათ გააკეთოთ მარყუჟი for (int i = 10; i > 0; i = i - 1). Ამ შემთხვევაში:
    • ცვლადს i ენიჭება მნიშვნელობა 10 ;
    • ეს მნიშვნელობა აკმაყოფილებს პირობას მე > 0 ;
    • ამიტომ, ციკლში მოთავსებული კოდის ბლოკი პირველად სრულდება;
    • მნიშვნელობა მემცირდება ერთით, მოცემული წესის მიხედვით და იღებს მნიშვნელობას 9 ;
    • კოდის ბლოკი მეორედ სრულდება;
    • ყველაფერი მეორდება აზრამდე მეთანაბარი 0 ;
    • Როდესაც მეტოლი ხდება 0 , მდგომარეობა მე > 0არ შესრულდება და ციკლის შესრულება დასრულდება;
    • კონტროლერი გადავა კოდზე მარყუჟის შემდეგ ამისთვის ;
  • ჩასვით კოდი, რომლის გადაღებაც გსურთ წყვილ ხვეულ ბრეკეტს შორის {} თუ შეიცავს ერთზე მეტ ინსტრუქციას;
  • განცხადებაში გამოცხადებული მრიცხველის ცვლადი ამისთვის, შეიძლება გამოყენებულ იქნას მარყუჟის შიგნით. მაგალითად, ამ ექსპერიმენტში ქინძისთავითანმიმდევრულად იღებს მნიშვნელობებს 2-დან 11-მდე და გადადის pinMode, საშუალებას გაძლევთ დააკონფიგურიროთ 10 პორტი მარყუჟში მოთავსებული ერთი ხაზით;
  • მრიცხველის ცვლადები ჩანს მხოლოდ მარყუჟის შიგნით. იმათ. თუ მიმართავთ ქინძისთავიციკლის წინ ან მის შემდეგ, შემდგენელი დაუშვებს შეცდომას გამოუცხადებელ ცვლადთან დაკავშირებით;
  • დიზაინი i = i - 1ზემოთ მოცემულ ახსნაში არ არის განტოლება! ჩვენ ვიყენებთ მინიჭების ოპერატორს = ცვლადში ჩასაწერად მედააყენეთ მნიშვნელობა მიმდინარე მნიშვნელობის ტოლი მე, შემცირდა 1 ;
  • გამოხატულება ++ pin- ეს არის ე.წ. ოპერატორი მატება , გამოიყენება ცვლადზე ქინძისთავი. ეს ინსტრუქცია მისცემს იგივე შედეგს, როგორც pin = pin + 1;
  • ოპერატორი მუშაობს გაზრდის მსგავსად შემცირება - - ღირებულების შემცირება ერთით. ამის შესახებ მეტი სტატიაში არითმეტიკული მოქმედებების შესახებ;
  • Მონაცემთა ტიპი ხელმოუწერელი ინტგამოიყენება ხელმოუწერელი რიცხვების შესანახად, ე.ი. მხოლოდ არაუარყოფითი . დამატებითი ბიტის გამო, რომელიც ახლა არ გამოიყენება ნიშნის შესანახად, შეგვიძლია მნიშვნელობების შენახვა მდე 65 535 ;
  • ფუნქცია მილისაბრუნებს მიკროკონტროლერის ჩართვის ან გადატვირთვის შემდეგ გასული მილიწამების რაოდენობას. აქ ჩვენ ვიყენებთ მას LED გადამრთველებს შორის დროის გასაზომად;
  • გამოხატვის გამოყენება (ms / 120) % 10ჩვენ განვსაზღვრავთ 10 LED-დან რომელი უნდა იყოს განათებული ახლა. პერიფრაზისთვის, ჩვენ განვსაზღვრავთ, რომელი 120 ms სეგმენტია ახლა და რა არის მისი რიცხვი მიმდინარე ათეულში. ჩვენ ვამატებთ სეგმენტის მიმდევრობის ნომერს იმ პორტის რიცხვს, რომელიც პირველ რიგში ჩნდება მიმდინარე ნაკრებში;
  • ის ფაქტი, რომ ჩვენ გამორთეთ LED ერთად ციფრული ჩაწერა (პინი, დაბალი)ჩართვის შემდეგ მხოლოდ 10 ms თვალით არ არის შესამჩნევი, რადგან ძალიან მალე ხელახლა გამოითვლება რომელი LED-ები ჩართოთ და ჩაირთვება - ახლახან ჩაქრება თუ შემდეგი.

კითხვები საკუთარი თავის შესამოწმებლად

  1. რატომ ვაკავშირებთ ამ ექსპერიმენტში LED მასშტაბს ტრანზისტორის გამოყენების გარეშე?
  2. თუ ჩვენ ჩავრთავთ LED-ებს მხოლოდ 5, 6, 7, 8, 9 პორტებზე, რა უნდა შეიცვალოს პროგრამაში?
  3. რა სხვა ინსტრუქცია შეიძლება გამოყენებულ იქნას ექვივალენტური მოქმედების შესასრულებლად ++ pin ?
  4. რა განსხვავებაა ტიპის ცვლადებს შორის ინტდა ხელმოუწერელი ინტ ?
  5. რას აბრუნებს ფუნქცია millis () ?
  6. როგორ გამოვთვალოთ პორტის ნომერი, რომელზეც გვინდა ჩავრთოთ LED ამ ექსპერიმენტში?

ამოცანები დამოუკიდებელი გადაწყვეტისთვის

  1. შეცვალეთ კოდი ისე, რომ LED-ები ჩართოთ წამში ერთხელ.
  2. პორტების გამორთვის გარეშე, დარწმუნდით, რომ შუქი ეშვება მხოლოდ სასწორის შუა ოთხი განყოფილების გასწვრივ.
  3. შეცვალეთ პროგრამა ისე, რომ ნაცვლად int pin = FIRST_LED_ PIN + (ms / 120) % 10ცეცხლის მოძრაობას აკონტროლებდა ციკლი ამისთვის .
  4. მავთულის გაცვლის გარეშე შეცვალეთ პროგრამა ისე, რომ შუქი საპირისპირო მიმართულებით აანთოს.

ამ ტუტორიალში ჩვენ გავაგრძელებთ LED-ებთან მუშაობას, მაგრამ LED-ების რაოდენობას გავზრდით 5-მდე. და გავაკეთებთ გაშვებული ცეცხლის ეფექტს. LED-ების გასაკონტროლებლად, ჩვენ გამოვიყენებთ Arduino პორტის მანიპულირებას. ჩვენ პირდაპირ დავწერთ მონაცემებს Arduino პორტებში. ეს უკეთესია, ვიდრე კონკრეტული კონტროლერის შეყვანის/გამოსვლების მუშაობა. ეს საშუალებას მოგცემთ დააყენოთ LED- ების მნიშვნელობები ერთი მოქმედებით.

Arduino UNO-ს აქვს 3 პორტი:

  • B (ციფრული I/Os 8-დან 13-მდე)
  • C (ანალოგური შეყვანა)
  • D (ციფრული I/O 0-დან 7-მდე)

თითოეულ პორტს აკონტროლებს 3 რეგისტრი. DDR რეგისტრი განსაზღვრავს, ფეხი (პინი) იქნება შემავალი თუ გამომავალი. PORT რეგისტრი შეიძლება გამოყენებულ იქნას პინის დასაყენებლად HIGH ან LOW. PIN რეესტრის გამოყენებით შეგიძლიათ წაიკითხოთ Arduino ფეხების მდგომარეობა მათი შეყვანისას.

ჩვენ გამოვიყენებთ B პორტს. პირველ რიგში, ჩვენ უნდა დავაყენოთ B პორტის ყველა პინი ციფრულ გამოსავალებად. პორტს B აქვს მხოლოდ 6 პინი. რეგისტრის ბიტები DDRB B პორტისთვის უნდა დაყენდეს 1-ზე, თუ ფეხი უნდა იქნას გამოყენებული როგორც OUTPUT, და 0-ზე, თუ ფეხი გამოყენებული იქნება როგორც INPUT. პორტის ბიტები დანომრილია 0-დან 7-მდე, მაგრამ ყოველთვის არ შეიცავს რვა ფეხს.

მაგალითი:

DDRB = B00111110; // დააყენეთ პორტი B ქინძისთავები 1-დან 5-მდე, როგორც გამოსავლები და 0, როგორც შესასვლელი.

გთხოვთ გაითვალისწინოთ, რომ Microchip მიკროკონტროლერებში პირიქითაა. 0 ბიტი - ფეხი მუშაობს როგორც გამომავალი, ხოლო 1 - როგორც შემავალი.

ჩვენს გაშვებულ ხანძარსაწინააღმდეგო პროექტში ჩვენ გამოვიყენებთ 5 გასასვლელს:

DDRB = B00011111; // დააყენეთ პორტი B ქინძისთავები 0-დან 4-მდე გამოსავლებად

B პორტში მნიშვნელობების ჩასაწერად, თქვენ უნდა გამოიყენოთ PORTB რეგისტრი. შეგიძლიათ აანთოთ პირველი LED ბრძანებით:

PORTB=B00000001;
პირველი და მეოთხე:
PORTB=B00001001;

ახლა ხედავთ, რამდენად მარტივად შეგვიძლია LED-ების ჩართვა და გამორთვა. ახლა მოდით ვისაუბროთ ცვლის ოპერატორებზე

არსებობს 2 ორობითი ცვლის ოპერატორი: მარცხენა ცვლის ოპერატორი<< и оператор сдвига вправо >>. მარცხენა ცვლის ოპერატორი<< заставляет все биты сдвигаться влево, соответственно оператор сдвига вправо >> ცვლის ბიტებს მარჯვნივ.

მაგალითი:

VarA = 1; // 00000001
varA = 1<< 0; // 00000001
varA = 1<< 1; // 00000010
varA = 1<< 2; // 00000100

ახლა დავუბრუნდეთ ჩვენს პროგრამას, რომელიც ნაჩვენებია ქვემოთ. ჩვენ უნდა შემოვიტანოთ 2 ცვლადი: პირველი ზევით ქვემოთშეიცავს მნიშვნელობას, სადაც გადაადგილება - ზემოთ ან ქვემოთ, და მეორე ცილონირა LED-ები ანათებს.

ფუნქციაში აწყობა()ჩვენ განვსაზღვრავთ, რომელი ფეხები უნდა იმუშაოს გამოსავლებად.

პროგრამის მთავარ ციკლში loop (), LED-ები თავის მხრივ ანათებენ ცვლადის გაზრდით ცილონი, და როდესაც ის მიაღწევს ყველაზე მაღალს, მაშინ ცვლადი ზევით ქვემოთენიჭება 0 და LED-ები ანათებენ თავის მხრივ ქვემოთ.

წრიული დიაგრამა

სქემა პურის დაფაზე

შენიშვნა

    გაითვალისწინეთ, რომ ამ ექსპერიმენტში რეზისტორები მოთავსებულია კათოდებსა და მიწას შორის, პულსარის ექსპერიმენტისგან განსხვავებით.

    ჩვენ ვუერთებთ LED-ებს ციფრულ პორტებს მე-2 პორტიდან დაწყებული. შეგვიძლია გამოვიყენოთ 0 და 1 პორტები, მაგრამ ისინი სერიული პორტების მონაცემთა არხებია და თითოეული დაფის ციმციმისთვის მოგვიწევს მათთან დაკავშირებული მოწყობილობების გამორთვა.

ესკიზი

unsigned int მონაცემთა ტიპი გამოიყენება ხელმოუწერელი მთელი რიცხვების შესანახად, ე.ი. მხოლოდ არაუარყოფითი. დამატებითი ბიტის გამო, რომელიც ახლა არ გამოიყენება ნიშნის შესანახად, ჩვენ შეგვიძლია შევინახოთ მნიშვნელობები 65,535-მდე ამ ტიპის ცვლადში.

გამოთქმით (ms / 120) % 10 ჩვენ განვსაზღვრავთ 10 LED-დან რომელი უნდა იყოს განათებული ახლა. პერიფრაზისთვის, ჩვენ განვსაზღვრავთ, რომელი 120 ms სეგმენტია ახლა და რა არის მისი რიცხვი მიმდინარე ათეულში. ჩვენ ვამატებთ სეგმენტის მიმდევრობის ნომერს იმ პორტის რიცხვს, რომელიც პირველია მიმდინარე ნაკრებში.

ის, რომ LED-ს DigitalWrite-ით (პინი, LOW) ჩართვით სულ რაღაც 10 ms-ში ვთიშავთ, თვალისთვის არ არის შესამჩნევი, რადგან. ძალიან მალე ხელახლა გამოითვლება რომელი LED-ები ჩართოთ და ჩაირთვება - ახლახან ჩაქრება თუ შემდეგი.

კითხვები საკუთარი თავის შესამოწმებლად

    რატომ ვაკავშირებთ ამ ექსპერიმენტში LED მასშტაბს ტრანზისტორის გამოყენების გარეშე?

    თუ ჩვენ ჩავრთავთ LED-ებს მხოლოდ 5, 6, 7, 8, 9 პორტებზე, რა უნდა შეიცვალოს პროგრამაში?

    რა სხვა ინსტრუქციას შეუძლია შეასრულოს ++ pin-ის ეკვივალენტი?

    რა განსხვავებაა int ტიპის და unsigned int ცვლადებს შორის?

    რას აბრუნებს millis() ფუნქცია?

    როგორ გამოვთვალოთ პორტის ნომერი, რომელზეც გვინდა ჩავრთოთ LED ამ ექსპერიმენტში?

ჩვენ ვამზადებთ სანათებს არდუინოს LED-ებიდან. ამ შემთხვევაში გამოიყენება Arduino Mega 2560, რომელსაც პოტენციურად შეუძლია მართოს 54 LED-იანი სარბენი ბილიკი. მაგრამ წრე და პროგრამა არ შეიცვლება, თუ იყენებთ სხვა კონტროლერებს ამ ტიპის Arduino პლატფორმიდან (UNO, Leonardo...)

LED-ების გაყვანილობის დიაგრამა Arduino Mega 2560-ზე.

ასე გამოიყურება ესკიზი სტანდარტული Arduino პროგრამირების აპლიკაციის ფანჯარაში.

არდუინოს პლატფორმაზე გაშვებული ნათურების განხორციელების პროგრამის ტექსტი.

int first_out = 11; //პირველი დისკრეტული გამომავალი

int last_out = 13; //ბოლო დისკრეტული გამომავალი

//ბლოკი შეყვანის/გამოსვლების და სხვა საწყისი მონაცემების ინიციალიზაციისთვის

ბოლო_გასული = ბოლო_გასული + 1; //დაამატე ერთი მარყუჟებში სწორი გამოყენებისთვის

//განსაზღვრეთ Arduino დაფის მე-11, მე-12 და მე-13 დისკრეტული ქინძისთავები, როგორც გამომავალი

for (i = first_out; i< last_out; i++) { pinMode(i, OUTPUT); }

for (t = first_out; t< last_out; t++) { //перебираем номера дискретных выходов 11,12,13 поочереди

digitalWrite(t, HIGH); //ანათებს შემდეგი LED

დაგვიანებით (500); //დაყოვნება 500 ms

for (i = first_out; i< last_out; i++) { digitalWrite(i, LOW); }//гасим все светодиоды

გირლანდში კონტროლირებადი LED-ების რაოდენობის გასაზრდელად, პროგრამას უბრალოდ უნდა შეცვალოს ცვლადების მნიშვნელობები პირველი_out და last_out. პირველი ცვლადი ინახავს კონტროლერის საწყის დისკრეტულ გამომავალს, ხოლო მეორე ცვლადი ინახავს ზედიზედ გამომავალი ჯგუფის ბოლო. მაგალითად, თუ გვსურს 10 LED-ის შეერთება გირლანდში, შევიყვანთ შემდეგ მნიშვნელობებს: first_out = 4, last_out = 13. და LED-ები ქინძისთავებს რიგით მე-4-დან მე-13-მდე. და უმჯობესია არ შეეხოთ დისკრეტული შეყვანა-გამოსვლების პირველ და მეორე პინებს, რადგან კომპიუტერთან დაკავშირებული usb პორტი ხელს უშლის მათ.