C# ile Arduino UNO kod yükleyici Uygulaması
Atmega328p Benzersiz Seri Numarası, Kod koruma
Arduino UNO üzerinde bulunan mikrodenetleyici : atmega328p-u kullanarak bir kod yazdık, derledik, bir hex dosyamız var, yazdığımız kodun, sadece "herhangi bir" atmega328p-u üzerinde çalışmasını istiyoruz, yani farklı bir mikrodenetleyiciyede çalışmasın, ya da "sadece" tek bir atmega328p-u üzerinde çalışsın istiyoruz, bir nevi kod koruma gibi, bir şekilde yazılı olan mikrodenetleyici üzerindeki kod okutularak başka bir mikrodenetleyiciye kopyalandığında çalışmasın istiyoruz.
İlk seçenek sadece kod uyumluluğunu denetlemek için kullanılabilir, hex kodu alınıp örnek olsun diye Atmega2560 a yüklendiğinde "uyumsuz olacağı düşünülerek" çalışması engellenebilir.
İkinci seçenekse, farklı bir atmega328p-u ya da atılmış olsa çalışmasın, burada kod korumadan söz edebiliriz. Peki bunu sağlamak için ne yapabiliriz? Örnek olsun diye atmega328p nin kendine özgü, her mikrodenetleyici için "benzersiz" bir seri numarası olsa, yine örnek olsun diye bu seri numarası 6F 75 57 37 37 57 FF 25 98 olsa, ve kodumuzun en başında desek ki, mikrodenetleyicinin seri numarasını oku, bizim bildiğimiz seri numarası ile karşılaştır doğru değilse sonsuz bir döngüye gir, dolayısıyla kodun geri kalanı hiç çalışmasın. Uygun bir çözüm gibi, peki atmega328p-u bize böyle bir olanak sağlıyor mu? Datasheet e bir göz atalım:
31.5 Serial Number The product has a serial number which offers a unique ID to identify a specified part while it is in the field. It consists of several bytes, which can be accessed from the signature address space. The Signature row includes factory-programmed data:
- ID for each device type
- Serial number for each device
- Calibration bytes for factory calibrated peripherals
burda bahsettiğine göre böyle bir imkan var, ancak nedir nerden buluruz nasıl okuruz gibi bir bilgi malesef yok.Ancak bu bilgiye aynı ailenin farklı bir ferdi olan atmega328pb için yayınlanan datasheet üzerinde rastlıyoruz.
Table 31.5 Signature Row Adressing
Siganure Byte | Z-Pointer |
Device Signature Byte 1 | 0x0000 |
Device Signarure Byte 2 | 0x0002 |
Device Signature Byte 3 | 0x0004 |
Rc Oscillator Calibration Byte | 0x0001 |
Serial Number Byte 1 | 0x000E |
Serial Number Byte 0 | 0x000F |
Serial Number Byte 3 | 0x0010 |
Serial Number Byte 2 | 0x0011 |
Serial Number Byte 5 | 0x0012 |
Serial Number Byte 4 | 0x0013 |
Serial Number Byte 6 | 0x0015 |
Serial Number Byte 7 | 0x0016 |
Serial Number Byte 8 | 0x0017 |
Şair burada ne anlatmak istemiş? ID for each device type ile kasıt mikrodenetleyicinin imzası yani kim olduğu bilgisi: Device Signature Byte ile verilmiş, Serial Number ise "biraz karışık olmakla birlikte" 9 ayrı adres üzerinde 8 bitlik veriler olacak şekilde; Serial Number Byte 0 ile Serial Number Byte 8 olarak kodlanmış.
Nasıl ulaşacağız bu bilgilere ? Bu noktada boot.h yardımıza koşuyor ve bize
boot_signature_byte_get(addr) gibi bir fonksiyon sunuyor.
boot.h main.cpp ye include edilip kullanılabilir, ;Atmel Studio için örnek kod:
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <avr/boot.h>
char devSignature[3];
char devSerial[9];
void getDevSignature(char* devsign)
{
for (size_t i = 0; i<3; i++)
{
devsign[i] = boot_signature_byte_get(i*2);
}
}
void getDevSerial(char* devSerial)
{
uint8_t add = 0;
for (size_t i = 0; i<9; i++)
{
if(i>=6)add=1;
devSerial[i+add] = boot_signature_byte_get(0x0E + i + add);
}
char tmp = devSerial[0];
devSerial[0]=devSerial[1];
devSerial[1]=tmp;
tmp = devSerial[2];
devSerial[2] = devSerial[3];
devSerial[3] = tmp;
tmp = devSerial[4];
devSerial[4] = devSerial[5];
devSerial[5] = tmp;
}
int main(void)
{
getDevSignature(devSignature);// Device Signature -hangi mikrodenetleyici
getDevSerial(devSerial); // Serial Number - seri numarası
}
Arduino IDE için örnek kod:
char devSerial[9];
#include <avr/boot.h>
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Device Signature : ");
for (uint8_t i = 0; i < 3; i++)
{
Serial.print(boot_signature_byte_get(0x0 + i*2),HEX);
Serial.print(" ");
}
Serial.println("");
getDevSerial(devSerial);
Serial.println("Device Serial Number : ");
for (uint8_t i = 0; i < 9; i++)
{
Serial.print(devSerial[i],HEX);Serial.print(" ");
}
}
void loop() {
// put your main code here, to run repeatedly:
}
void getDevSerial(char* devSerial)
{
uint8_t add = 0;
for (size_t i = 0; i<9; i++)
{
if(i>=6)add=1;
devSerial[i+add] = boot_signature_byte_get(0x0E + i + add);
}
char tmp = devSerial[0];
devSerial[0]=devSerial[1];
devSerial[1]=tmp;
tmp = devSerial[2];
devSerial[2] = devSerial[3];
devSerial[3] = tmp;
tmp = devSerial[4];
devSerial[4] = devSerial[5];
devSerial[5] = tmp;
}
Elimdeki 3 değişik atmega328p ile denedim her birinde farklı seri numaraları elde ettim, bir eşleşme olacağını düşünmüyorum, deneyenler yorumlara yazabilir.
-Kolay gelsin.
Arduino UNO, Atmel Studio üzerinden programlamak | AVR Programlama - Registers
Arduino üzerinde bazı şeyleri öğrendik, hazır kütüphaneler üzerinde projelerimizi çalıştırdık, ama sanki IDE üzerinde eksik bişey var gibi, mesela bir IntelliSense olaydı ne güzel olmaz mıydı? hani şu değişken adını yazmaya başladığımızda tamamlama önerileri çıkartan, ya da nesne tabanlı programlamada kullandığımız; nesne. yazınca nesnenin tüm özelliklerine ulaşabildiğimiz yardımcı pencere açan.. bunun için Arduino yu bir adım ileriye taşıyan Atmelin kendi kodlayıcısı Atmel Studio (artık yerini MicroChip Studio alıyor) mevcut, Visual Studio kullananların hemen alışacağı (neredeyse aynısı) bir kodlama arayüzü, kod yazmak için biraz datasheet karıştırmak gerekiyor. Ancak kontrolün sizde olduğunu bilmek bir ayrıcalık, Arduino IDE ile yazılmış bir led yakın söndürme kodu :
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
avrdude: 924 bytes of flash written,
924 bytes yer kaplarken, aynı işi yapan Atmel Studio ile register seviyesinde yazılmış olan şu kod :
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB |= (1 << DDB5);
while (1)
{
PORTB |= (1<<PORTB5);
_delay_ms(1000);
PORTB = 0;
_delay_ms(1000);
}
}
avrdude.exe: writing flash (176 bytes):
sadece 176 bytes yer kaplıyor, yaklaşık 5.25 katı, 176 bytes ile yapılabilecek işi 924 bytes ile yapmak, nerden baksak bir mühendisin fiyat/performans tarzına uymuyor.
Peki konu sadece kodun hafızada kapladığı alan mı acaba? Hıza da bakalım mı ?
void setup() { pinMode(3,OUTPUT); } void loop() { digitalWrite(3,HIGH); digitalWrite(3,LOW); }
yukarıda gördüğünüz Arduino ide de yazılmış bir kod sizce hangi frekanslarda 3 pini açıp kapatabiliyordur?
112 Khz mi? Hey dostum tek yapabildiğin bu mu? hadi onu geçtim, 1ms lik aralıklarla yaptığın gecikmeler de neyin nesi ?
Studio 'ya ve register level 'e geçelim :
#include <avr/io.h>
int main(void)
{
DDRD |= (1<<DDD3);
/* Replace with your application code */
while (1)
{
PORTD = 8;
PORTD = 0;
}
}
Evet şimdi konuşmaya başladın : 3.2 Mhz :) 27.8 kat daha hızlı ve alt tarafta görebileceğiniz üzere 1ms lik gecikemeler de artık YOK.
Tamam, kararımızı verdik, kodumuzu yazdık, başka hiçbir ek donanım gereksinimi olmadan kodumuzu nasıl Arduino UNO kartımıza yükleyeceğiz?
Türksat Saat Kanalı ve IRIG-B Time Code
Türksat Saat Kanalından Saat Bilgisi Nasıl Alınır? Uyduda kanalları dolaşırken, şu Türksat Saat kanalı hep dikkatimi çekmiştir. Özellikle S...
-
Arduino güç özellikleri konusunda detaylıca anlattığımız üzere, Arduino UNO için konuşuyorsak; mikro denetleyicimizin anlamlandırab...
-
Bu yazıda, Arduino ile ssd1306 oled ekranın SSD1306TUR kütüphanesiyle kullanımına ve tüm fonksiyonlarına bakıyor olacağız. Arduino demişke...
-
SSD1306 Oled Ekran Türkçe Karakter Kullanımı Arduino ya da benzeri gömülü sistem uygulamalarımızda ekran ihtiyaçlarımızdan birini de SS...
-
Nodemcu (esp8266) ile İnternetten Namaz Vakitlerini Çekme Nodemcu ile nesnelerin interneti projelerinde yeni bir yazıdan herkese merhaba, İ...
-
Röle Nedir? Röle en kısa tabirle elektrikle kontrol edilen mekanik bir anahtarlama elemanıdır. Kontrol uçlarına gerekli miktarda " bu m...
-
Esp8266 Api ile Hava Durumunu Çekme Nodemcu (esp8266) ile openweathermap.org 'un sağlamış olduğu api hizmeti ile illerin hava duru...
-
Türksat Saat Kanalından Saat Bilgisi Nasıl Alınır? Uyduda kanalları dolaşırken, şu Türksat Saat kanalı hep dikkatimi çekmiştir. Özellikle S...
-
Arduino ile BMP280 basınç ve sıcaklık sensörü nün bağlantısına, nasıl kullanıldığına ve örnek kod una bakıyor olacağız bu yazıda. Atmosferi...
-
Arduino ile ADC ölçümlerinde hep 5V kullanıldığı dikkatinizi çekmiştir. İşin aslı AVR 'nin bize sunduğu analog reference voltage de...
-
Bu yazımızda Arduino UNO 'nun güç bölümünü inceliyoruz. Bu hemen hemen aynı yapıda olan arduino kartları için benzer özellikler gö...