Სარჩევი:

Arduino UNO Logic Sniffer: 8 ნაბიჯი (სურათებით)
Arduino UNO Logic Sniffer: 8 ნაბიჯი (სურათებით)

ვიდეო: Arduino UNO Logic Sniffer: 8 ნაბიჯი (სურათებით)

ვიდეო: Arduino UNO Logic Sniffer: 8 ნაბიჯი (სურათებით)
ვიდეო: ჯენიფერ გეიზი - "უკიდურესი სიმაღლე" - აუდიო წიგნი 2024, ივლისი
Anonim
Arduino UNO Logic Sniffer
Arduino UNO Logic Sniffer

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

შემდეგ დავინტერესდი, რომელი აპლიკაციით შეიძლება იყოს ეს სასარგებლო და როგორ გამოვცადო. რამდენადაც მინდა ლოგიკური ანალიზატორი მივიღო გარკვეული დროის განმავლობაში, მე გადავწყვიტე მისი დანერგვა Arduino UNO– ს დაფაზე, მხოლოდ ფუნქციის შესამოწმებლად და ვნახოთ, შეგვიძლია თუ არა მისგან კარგი შედეგების მიღება.

მე არ ვარ ერთადერთი, ვინც ეს იდეა გამიჩნდა და თქვენ ბევრ მათგანს ნახავთ მხოლოდ "Arduino Logic Analyzer" - ის გუგლით. პროექტის დასაწყისში, როგორც ის ექსპერიმენტად დაიწყო, მე არც კი ვიცოდი, რომ ხალხმა უკვე შეძლო ამის გაკეთება და შთაბეჭდილება მოახდინა იმ კარგმა შედეგებმა, რაც მათ მიაღწიეს ამ პატარა ტექნიკით. თუმცა, მე ვერ ვიპოვე სხვა პროექტი შეყვანის გადაღების ერთეულის გამოყენებით, ასე რომ, თუ ეს უკვე გინახავთ, შემატყობინეთ!

მოკლედ რომ ვთქვათ, ჩემი ლოგიკური ანალიზატორი იქნება:

  • გქონდეს ერთი არხი,
  • აქვს გრაფიკული ინტერფეისი,
  • დაუკავშირდით ინტერფეისს USB– ით,
  • გაუშვით Arduino UNO დაფაზე.

მას საბოლოოდ ექნება 800 სინჯის მეხსიერების სიღრმე და შეძლო წარმატებით გადაეღო 115200 ბაუდის UART შეტყობინება (მე ნამდვილად არ გამოვცადე ის უფრო მაღალი სიჩქარით).

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

მარაგები

მინდოდა ანალიზატორი მაქსიმალურად მარტივი ყოფილიყო, ასე რომ ძალიან ცოტა ტექნიკა მჭირდებოდა.

თქვენ დაგჭირდებათ:

  • Arduino UNO დაფა (ან ექვივალენტი, სანამ ის ეყრდნობა ATMEGA328P MCU),
  • კომპიუტერი,
  • რაღაც გამოსწორება (Arduino UNO– ს სხვა დაფა მშვენივრად მუშაობს ტესტების ჩასატარებლად).

კოდი Arduino UNO და ვებ ინტერფეისი შეგიძლიათ იხილოთ აქ. თქვენ ასევე დაგჭირდებათ p5.serialcontrol და PulseView პროგრამული უზრუნველყოფა.

ნაბიჯი 1: მუშაობის პრინციპი

მუშაობის პრინციპი
მუშაობის პრინციპი

იდეა მარტივია. თქვენ ირჩევთ გადაღების პარამეტრებს და დააჭირეთ "შეძენას". ვებ ინტერფეისი გაგზავნის მათ p5.serialcontrol პროგრამულ უზრუნველყოფაზე, რაც საშუალებას გვაძლევს გამოვიყენოთ სერიული ინტერფეისი ბრაუზერიდან, რადგან მას არ შეუძლია პირდაპირ წვდომა. P5.serialcontrol პროგრამული უზრუნველყოფა შემდეგ გადასცემს ინფორმაციას Arduino UNO დაფაზე, რომელიც ინახავს მონაცემებს და აგზავნის მათ ინტერფეისს იმავე გზით.

Მარტივი! ისე … რადგან მე ნამდვილად არ ვარ კარგი ადამიანების/მანქანების ინტერფეისის პროგრამირებაში ან ვებ ტექნოლოგიებში, ჩემი, რა თქმა უნდა, ცოტა მახინჯი და ხარვეზია. მაგრამ ეს მაძლევს საშუალებას დავიწყოთ გადაღება და დავიბრუნო ჩემი მონაცემები, რაც სწორედ ის არის შექმნილი, ასე რომ, მე ვფიქრობ, რომ კარგია. უფრო სერიოზული ანალიზისთვის, მე შემოვიტან ჩემს ჩანაწერებს PulseView– ში, რომლის გამოყენებაც ადვილია და გვთავაზობს მახასიათებლებისა და პროტოკოლის დეკოდერების კარგ კომპლექტს, როგორც ამას მოგვიანებით ვნახავთ.

Arduino UNO- ს შეყვანის ერთეულის კონფიგურაცია შესაძლებელია საათის სხვადასხვა განყოფილების გამოყენებისათვის, რითაც ამცირებს რეზოლუციას, მაგრამ გაზრდის დაგვიანებას გადავსებამდე. მას ასევე შეუძლია გამოიწვიოს ზრდის, დაცემის ან ორივე კიდეების დაწყება მონაცემების გადაღების მიზნით.

ნაბიჯი 2: Arduino UNO Sketch

Arduino UNO ესკიზი
Arduino UNO ესკიზი

მე დავწერე და შევადგინე ესკიზი Arduino IDE– ით. მე პირველად დავიწყე Timer1- ის დაყენება "ნორმალურ" რეჟიმში, მის TCCR1A და TCCR1B რეგისტრებში ჩაწერით (). შემდეგ გავაკეთე რამდენიმე ფუნქცია, რათა შემდგომში შემსუბუქდეს მისი გამოყენება, მაგალითად ის, რაც საათის განყოფილებას ადგენს სახელწოდებით "setTim1PSC ()". მე ასევე დავწერე ფუნქციები Timer1 შეყვანის გადაღების ერთეულის გასააქტიურებლად და გამორთვისთვის და გადატვირთვის შეფერხებებისათვის.

მე დავამატე "ნიმუშების" მასივი, რომელიც ინახავს შეძენილ მონაცემებს. ეს არის გლობალური მასივი, რომელიც მე დავაყენე "არასტაბილურზე", რათა შემგროვებელმა ხელი შეუშალოს ოპტიმიზაციას და განათავსოს იგი, როგორც ამას აკეთებდა ჩემი პირველი კომპილირების დროს. მე განვსაზღვრე მას, როგორც "uint16_t" მასივი, რადგანაც ტაიმერი 1 არის 16 ბიტიანი, სიგრძით 810. ჩვენ ვწყვეტთ გადაღებას 800 მნიშვნელობებზე, მაგრამ რადგანაც ტესტირება ტარდება შეფერხებების გარეთ აშკარა სიჩქარის მიზეზების გამო, მე ავირჩიე 10 -ის შენარჩუნება მეტი მნიშვნელობა, რათა თავიდან იქნას აცილებული გადინება. დანარჩენი კოდისთვის რამდენიმე დამატებითი ცვლადი, ესკიზი იყენებს 1313 ბაიტს (88%) მეხსიერებას, რის გამოც დაგვრჩება 235 ბაიტი თავისუფალი ოპერატიული მეხსიერება. ჩვენ უკვე ვიყენებთ მეხსიერების მაღალ დონეს და მე არ მინდოდა მეტი მოცულობის დამატება, რადგან ამან შეიძლება გამოიწვიოს უცნაური ქცევები მეხსიერების ძალიან მცირე სივრცის გამო.

ჩემი სწრაფვის, რომ ყოველთვის გავზარდო შესრულების სიჩქარე, მე გამოვიყენე ფუნქციის პოინტერები ნაცვლად if განცხადებების შეფერხებების შიგნით, რათა მათი შესრულების დრო მინიმუმამდე შემცირდეს. დამაგრების პინი ყოველთვის იქნება Arduino UNO ნომერი 8, რადგან ის ერთადერთია, რომელიც დაკავშირებულია Timer1– ის შეყვანის გადაღების ერთეულთან.

გადაღების პროცესი ნაჩვენებია ზემოთ მოცემულ სურათზე. ის იწყება მაშინ, როდესაც Arduino UNO მიიღებს მოქმედ UART მონაცემთა ჩარჩოს, რომელიც შეიცავს სასურველ გადაღების პარამეტრებს. შემდეგ ჩვენ ვამუშავებთ ამ პარამეტრებს სწორი რეგისტრების კონფიგურაციით არჩეულ ზღვარზე გადასაღებად და საათის სწორი განყოფილების გამოყენებით. შემდეგ ჩვენ ვააქტიურებთ PCINT0 (პინის შეცვლა) შეწყვეტას სიგნალის პირველი ზღვრის გამოსავლენად. როდესაც ჩვენ ვიღებთ მას, ჩვენ აღვადგენთ Timer1 მნიშვნელობას, გავთიშავთ PCINT0 წყვეტს და ვააქტიურებთ ICU (Input Capture Unit) შეწყვეტას. იმ მომენტიდან, სიგნალის ნებისმიერი ვარდნა/ამოსვლა ზღვარზე (დამოკიდებულია არჩეული კონფიგურაციის მიხედვით), გამოიწვევს შეყვანის გადაღების ერთეულს, რითაც ინახავს ამ მოვლენის დროის ნიშნულს ICR1 რეგისტრში და ასრულებს შეწყვეტას. ამ შეფერხებაში ჩვენ ICR1 რეგისტრის მნიშვნელობას ვდებთ ჩვენს "ნიმუშების" მასივში და ვამატებთ ინდექსს მომდევნო გადაღებისთვის. როდესაც ტაიმერი 1 ან მასივი გადავსებულია, ჩვენ ვთიშავთ გადაღების შეწყვეტას და მონაცემებს ვუბრუნებთ ვებ ინტერფეისს UART- ის საშუალებით.

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

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

ნაბიჯი 3: ვებ ინტერფეისი და P5.js

ვებ ინტერფეისი და P5.js
ვებ ინტერფეისი და P5.js

როგორც სათაურიდან ჩანს, ვებ ინტერფეისი შეიქმნა p5.js. მათთვის, ვინც უკვე არ იცის, გირჩევთ, წახვიდეთ და შეამოწმოთ ვებ გვერდი, რადგან ის მართლაც კარგი ბიბლიოთეკაა. ის დაფუძნებულია დამუშავებაზე, არის მარტივი გამოსაყენებლად, გაძლევთ საშუალებას მიიღოთ კარგი შედეგები ძალიან სწრაფად და კარგად არის დოკუმენტირებული. სწორედ ამ მიზეზების გამო ავირჩიე ეს ბიბლიოთეკა. მე ასევე გამოვიყენე quicksettings.js ბიბლიოთეკა მენიუებისთვის, grafica.js ერთი ჩემი მონაცემების გამოსახვისთვის და p5.serportport ბიბლიოთეკა Arduino UNO– სთან კომუნიკაციისთვის.

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

ნაბიჯი 4: სისტემის დაყენება

უპირველეს ყოვლისა, ჩამოტვირთეთ Arduino UNO და ინტერფეისის კოდი აქ, თუ ეს უკვე არ გაკეთებულა. ამის შემდეგ შეგიძლიათ გადააპროგრამოთ თქვენი Arduino UNO დაფა "UNO_LS.ino" ესკიზით Arduino IDE საშუალებით.

თქვენ უნდა გადმოწეროთ p5.serialcontrol პროგრამული უზრუნველყოფა მისი github საცავიდან. თქვენ უნდა მიიღოთ zip ფაილი, რომელიც შეესაბამება თქვენს ოპერაციულ სისტემას (მე მხოლოდ Windows- ზე გამოვცადე). ამოიღეთ zip საქაღალდეში, დაიწყეთ მასში ნაპოვნი შესრულებადი და დატოვეთ ასე. ნუ ეცდებით რომელიმე სერიულ პორტთან დაკავშირებას, უბრალოდ დატოვეთ ის ფონზე გაშვებული, ის გამოყენებული იქნება როგორც სარელეო.

გახსენით საქაღალდე "ინტერფეისი". თქვენ უნდა იპოვოთ ფაილი სახელწოდებით "index.html". გახსენით იგი თქვენს ბრაუზერში, ეს არის ვებ ინტერფეისი.

და ეს არის ის! თქვენ არ გჭირდებათ დამატებითი ბიბლიოთეკების გადმოტვირთვა, ყველაფერი უნდა იყოს ჩართული ჩემს მიერ მოწოდებულ პაკეტში.

ნაბიჯი 5: კავშირი, კონფიგურაცია და შეძენა

კავშირი, კონფიგურაცია და შეძენა
კავშირი, კონფიგურაცია და შეძენა

Arduino UNO დაფასთან ინტერფეისის დასაკავშირებლად, უბრალოდ შეარჩიეთ შესაბამისი პორტი სიაში და დააჭირეთ ღილაკს "გახსნა". თუ ოპერაცია წარმატებული იყო, "სახელმწიფოს" შეტყობინებამ უნდა აჩვენოს რაღაც "COMX გაიხსნა".

ახლა თქვენ შეგიძლიათ აირჩიოთ თქვენი გადაღების პარამეტრები. პირველი არის ზღვრის შერჩევა. მე გირჩევთ ყოველთვის გამოიყენოთ "ორივე", რადგან ის მოგცემთ რეალურ სიგნალს საუკეთესოდ. თუ "ორივე" პარამეტრი ვერ ახერხებს სიგნალის დაჭერას (თუ სიგნალის სიხშირე ძალიან მაღალია, მაგალითად), შეგიძლიათ სცადოთ "ამოსვლის" ან "დაცემის" პირას პარამეტრი, იმისდა მიხედვით, თუ რა სიგნალს ხედავთ.

მეორე პარამეტრი არის საათის გაყოფა. ის მოგცემთ რეზოლუციას, რომლის დროსაც თქვენ შეძლებთ სიგნალის დაჭერას. თქვენ შეგიძლიათ აირჩიოთ დაყოფის კოეფიციენტის დაყენება "8", "64", "256" და "1024". Arduino UNO- ს დაფა იყენებს 16MHz კვარცს მიკროკონტროლერის დასაყენებლად, ამიტომ შერჩევის სიხშირე იქნება "16MHz/გაყოფის ფაქტორი". ფრთხილად იყავით ამ პარამეტრთან დაკავშირებით, რადგან ის ასევე განსაზღვრავს რამდენ ხანს შეძლებთ სიგნალის გადაღებას. ვინაიდან ტაიმერი 1 არის 16 ბიტიანი ქრონომეტრი, გადატვირთვის წინ დაშვებული დრო იქნება "(2^16)*(გაყოფის ფაქტორი)/16 მჰც". თქვენს მიერ არჩეული პარამეტრიდან გამომდინარე, ის იქნება 33 მილიონამდე 4. 4.2 წამამდე. გქონდეთ არჩევანი გონებაში, მოგვიანებით დაგჭირდებათ.

ბოლო პარამეტრი არის ხმაურის შემსუბუქებელი. მე არ ჩავატარე ბევრი ტესტირება მასზე და თქვენ არ დაგჭირდებათ შემთხვევების 99% -ში, ასე რომ უბრალოდ დატოვეთ უკონტროლო. მათთვის, ვისაც ეს ჯერ კიდევ აინტერესებს, შეგიძლიათ მოძებნოთ ხმაურის შემსუბუქებელი ATMEGA328P– ის მონაცემთა ცხრილის ტაიმერის/მრიცხველის 1 განყოფილებაში.

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

მას შემდეგ რაც ყველაფერი სწორად არის კონფიგურირებული, შეგიძლიათ დააჭიროთ ღილაკს "შეძენა".

ნაბიჯი 6: შედეგების გადაღება და CSV მონაცემების ექსპორტი

შედეგების გადაღება და CSV მონაცემთა ექსპორტი
შედეგების გადაღება და CSV მონაცემთა ექსპორტი

მას შემდეგ, რაც თქვენი Arduino UNO დაასრულებს გადაღებას, ის ავტომატურად დააბრუნებს მონაცემებს ვებ ინტერფეისზე, რომელიც ასახავს მათ. თქვენ შეგიძლიათ გაადიდოთ ან გაადიდოთ მარჯვენა სლაიდერი და იმოგზაუროთ ნიმუშებში ქვედა ერთით.

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

პირველი ნაბიჯი არის csv ფაილის ექსპორტი, რომელიც შეიცავს თქვენს ყველა მონაცემს. ამისათვის თქვენ უბრალოდ უნდა დააჭიროთ ღილაკს "ექსპორტი" ვებ ინტერფეისიდან. მოთხოვნის შემთხვევაში შეინახეთ ფაილი ცნობილ ადგილას.

ახლა გახსენით PulseView. მენიუს ზედა ზოლში დააწკაპუნეთ "გახსნაზე" (საქაღალდის ხატულა) და აირჩიეთ "მძიმით გამოყოფილი მნიშვნელობების იმპორტი …". შეარჩიეთ ადრე გენერირებული csv ფაილი, რომელიც შეიცავს თქვენს მონაცემებს.

პატარა ფანჯარა გამოჩნდება. დატოვეთ ყველაფერი ისე, როგორც არის, თქვენ უბრალოდ უნდა შეცვალოთ "შერჩევის" პარამეტრი გადაღებისთვის არჩეული საათის გაყოფის ფაქტორის მიხედვით. თქვენი შერჩევის სიხშირე იქნება "16 MHz/(გაყოფის ფაქტორი)". შემდეგ დააჭირეთ ღილაკს "კარგი", თქვენი სიგნალი უნდა გამოჩნდეს ეკრანზე.

ნაბიჯი 7: PulseView სიგნალის ანალიზი

PulseView სიგნალის ანალიზი
PulseView სიგნალის ანალიზი

PulseView– ს აქვს მრავალი პროტოკოლის დეკოდირება. მათზე წვდომისთვის დააჭირეთ მენიუს ზედა ზოლში "პროტოკოლის დეკოდირების დამატება" (ყველაზე სწორი ინსტრუმენტი). ჩემი ექსპერიმენტისთვის, მე უბრალოდ გავგზავნე მარტივი UART შეტყობინება 9600 ბაუდზე, ამიტომ ვეძებე "UART".

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

ნაბიჯი 8: დასკვნა

დასკვნა
დასკვნა

მაშინაც კი, თუ პროექტი თავიდანვე ექსპერიმენტი იყო, მე კმაყოფილი ვარ მიღებული შედეგით. მე შევძელი UART სიგნალების აღება 115200 ბაუდზე "ორივე" პირას რეჟიმში უპრობლემოდ, და მე კი მოვახერხე 230400 ბაუდამდე აწევა "დაცემის" პირას რეჟიმში. თქვენ შეგიძლიათ ნახოთ ჩემი ტესტის დაყენება ზემოთ მოცემულ სურათზე.

ჩემს განხორციელებას აქვს რამდენიმე ნაკლი, დაწყებული იმით, რომ მას შეუძლია დაიჭიროს მხოლოდ ერთი სიგნალი ერთდროულად, ვინაიდან მხოლოდ Arduino UNO- ს პინი 8 არის "შეყვანის დაჭერის უნარი". თუ თქვენ ეძებთ Arduino– ს ლოგიკურ ანალიზატორს მეტი არხით, გადახედეთ Catoblepas– ს.

თქვენ არ შეგიძლიათ ელოდოთ, რომ Arduino UNO- ს შეეძლება სიგნალების გადაღება მაღალი სიხშირით (ზოგიერთი MHz), რადგან ის მხოლოდ 16 MHz სიხშირით არის დაკავებული (თუ ვინმემ ეს გააკეთა, მე დაინტერესებული ვიქნებოდი მისი მეთოდის ხილვით). თუმცა, მე მაინც შთაბეჭდილება მოახდინა იმ შედეგებზე, რისი მოპოვებაც ჩვენ შეგვიძლია ამ ATMEGA328P მიკროკონტროლერისგან.

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

ეს იყო ჩემი პირველი ინსტრუქცია და მგონი გრძელი. ვიმედოვნებ, რომ თქვენთვის საინტერესო კითხვა იყო.

შემატყობინეთ, თუ აღმოაჩენთ შეცდომებს, ან გაქვთ რაიმე შეკითხვა!

გირჩევთ: