Raspberry pi pico ADC kullanımı

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Arduino IDE kullanarak raspberry pi pico'nun ADC sinden veri okuma nasıl yapılır ona bakalım. Öncelikle piconun pin yapısını gösteren şekle bakalım

1656876149417.png


Buradan 26 numaralı pinin ADC0 girişi olduğunu görüyoruz. Sadece bu pini INPUT olarak yapılandırıp okuyalım bakalım ne gelecek.

C++:
#define PIN_ADC0 26

void setup()
{
  pinMode(PIN_ADC0, INPUT);

  Serial.begin(115200);
}

void loop()
{
  while (1)
  {
    int value = analogRead(PIN_ADC0);

    char buffer[20];
    sprintf(buffer, "value = %d\n", value);
    Serial.print(buffer);
  }
}

Bu programı çalıştırınca analog pin de boşta iken şuna benzer değerler okuyorum

Kod:
value = 234
value = 234
value = 234
value = 232
value = 232
value = 231
value = 232
value = 232
value = 231
value = 233
value = 231
value = 231
value = 234
value = 231
value = 232
value = 232
value = 233
value = 233
value = 232
value = 235
value = 232
value = 233
value = 233
value = 235
value = 233
value = 232
value = 231
value = 232
value = 232
value = 232
value = 232
value = 232
value = 234
value = 232
value = 232
value = 232
value = 233
value = 234
value = 232
value = 232
value = 233
value = 233
value = 232
value = 235
value = 232
value = 234
value = 231
value = 231
value = 231
value = 233
value = 232
value = 233
value = 232
value = 233
value = 231
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
ADC0 girişini şase yapınca şu değerler geliyor:

Kod:
value = 4
value = 4
value = 4
value = 4
value = 4
value = 5
value = 5
value = 5
value = 4
value = 5
value = 4
value = 5
value = 4
value = 5
value = 4
value = 4
value = 4
value = 5
value = 5
value = 5
value = 5
value = 5
value = 5
value = 5
value = 5
value = 5
value = 4
value = 5
value = 5
value = 5
value = 4
value = 4
value = 5
value = 5
value = 5
value = 4
value = 5
value = 4
value = 5
value = 5
value = 4
value = 5
value = 4
value = 4
value = 5
value = 4
value = 5
value = 5
value = 4
value = 5
value = 5
value = 5
value = 5
value = 5
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Hmm ADC0 girişine 1V veriyorum, full 0 okuyorum. Acaba ADC_VREF pinine referans voltaj mı bağlamak lazım diye düşündüm ve ADC_VREF'i 3.3V a bağladım. Hala full 0 okuyorum.
 

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
Hmm ADC0 girişine 1V veriyorum, full 0 okuyorum. Acaba ADC_VREF pinine referans voltaj mı bağlamak lazım diye düşündüm ve ADC_VREF'i 3.3V a bağladım. Hala full 0 okuyorum.
Abi boştaki pini 234 okuyup 1v verince nasıl sıfır okuyorki?
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Zaten şimdi şemaya bakınca ADC_AVDD bir RC filtre üzerinden içeride 3.3 V a bağlanmış. Anlamsız iş yapmışım, sadece R7 yi kısa devre etmişim.

1656866411185.png
 

tekosis

Aktif Üye
Katılım
16 Eylül 2019
Mesajlar
241
Hocam koddaki pin mod tanımlamasını kaldırıp setup'ta sadece serial.begin kodu kalsa, böyle deneseniz nasıl olur?
 

Ahmet

Kıdemli Üye
Katılım
31 Mayıs 2021
Mesajlar
2,597
IMG_20220703_194858.jpg


Buraya bakmayınca tansiyonum düşüyor ücra köşedeki bir avmden bakıyorum :katil2:
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Gene programlama hataları vermeye başladı bu. Daha önce sopadan anlıyordu şimdi sürekli programlama hatası veriyor düzelmiyor artık.
 

Ahmet

Kıdemli Üye
Katılım
31 Mayıs 2021
Mesajlar
2,597
Sayın pico büyükelçisi söyle bakalım problem ne, neden programlanmıyor bu meret? :)
Abi senin atölyen sağlam söyleyeceğim yönergeleri çok rahat gözden geçirebilirsin.

Bu picoyu boot moduna sokan bir entegre var o entegreye gelen usb data karışya geçiyor mu ona bakabilirsin ilk olarak.

2 olarak şöyle bir çözüm biliyorum bootsel butonuna basarken boş program yüklemek.

İçinde blink yüklüyken boot butonuna basınca blink yapmaya devam ediyor mu?
 

Ahmet

Kıdemli Üye
Katılım
31 Mayıs 2021
Mesajlar
2,597
1 saate evdeyim senin pico konularına didik didik ettiğim bilgilerimi yazayım
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Evet sorunu buldum. SMU'daki banana jack'leri BNC ye dönüştürüp 1x probla veriyordum voltajı. Adaptörü ters bağlamışım ve negatif voltaj veriyormuşum. Neyseki SMU yu 10 mA ile sınırlamıştım belki de bu sayede bozulmaktan kurtuldu pico. Şimdi mantıklı çalışıyor.

0 V verince (not: bu şaseye bağlamaktan farklı. Şase kesin 0, ama SMU 0 V veriyorken kablolar vs var). Dikkat edilirse ara ara pikler var. Ortalamasına sonra bakacağız.

Kod:
value = 4
value = 4
value = 3
value = 5
value = 4
value = 0
value = 4
value = 4
value = 3
value = 3
value = 5
value = 5
value = 4
value = 15
value = 5
value = 5
value = 5
value = 6
value = 5
value = 10
value = 4
value = 3
value = 5
value = 4
value = 6
value = 5
value = 4
value = 5
value = 5
value = 0
value = 7
value = 5
value = 5
value = 5
value = 5
value = 1
value = 6
value = 6
value = 5
value = 5
value = 5
value = 13
value = 5
value = 5
value = 5
value = 5
value = 4
value = 5
value = 4
value = 5
value = 5
value = 12
value = 4
value = 15
value = 5
value = 5
value = 5
value = 5
value = 4
value = 6
value = 5
value = 6
value = 5
value = 5
value = 5

3.3 V verince alınan değerler. Bunlar tam olarak birbiri ile aynı olduğuna göre ADC pozitif yönde satürasyona uğramış. Demekki ADC nin referans voltajı 3.3 V dan biraz daha az, bu da mantıklı, neticede bir RC filtre üzerinden ulaşıyor referans voltajı.

Kod:
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
value = 1023
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Şimdi RP2040 ın referans voltaj girişini ölçtüm 3.217 V. SMU'dan tam olarak bu voltajı veriyorum ve beklendiği gibi maksimum ADC değerini alıyoruz. Tabi burada hafif değişkenlik var çünkü voltaj referans USB bus voltajı ve o da sürekli değişiyor.

Kod:
value = 1020
value = 1023
value = 1022
value = 1021
value = 1022
value = 1021
value = 1023
value = 1019
value = 1015
value = 1020
value = 1020
value = 1021
value = 1020
value = 1023
value = 1009
value = 1021
value = 1020
value = 1021
value = 1020
value = 1021
value = 1020
value = 1022
value = 1020
value = 1023
value = 1020
value = 1019
value = 1020
value = 1022
value = 1020
value = 1021
value = 1021
value = 1022
value = 1022
value = 1020
value = 1020
value = 1020
value = 1023
value = 1021
value = 1020
value = 1019
value = 1020
value = 1021
value = 1021
value = 1023
value = 1021
value = 1022
value = 1021
value = 1020
value = 1021
value = 1021
value = 1020
value = 1020
value = 1023
value = 1020
value = 1019
value = 1020
value = 1020
value = 1020
value = 1021
value = 1022
value = 1020
value = 1020
value = 1021
value = 1020
value = 1014
value = 1020
value = 1021
value = 1020
value = 1019
value = 1020
value = 1020
value = 1019
value = 1022
value = 1023
value = 1022
value = 1022
value = 1018
value = 1021
value = 1020
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Yani şimdiye kadar şunu anlıyoruz: Herhangi bir yapılandırma yapmazsak, pico ADC sine 0 - 3.2 V aralığında bir giriş voltajı verebiliyoruz ve dijital olarak da 0 - 1023 arasında bir değer okuyoruz. 0 - 4096 arasında okuyabilir hale getirelim sonra da lineerlik testini yapalım.
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Internette araştırınca, ADC bit sayısını analogReadResolution fonksiyonu ile ayarladığımızı görüyorum. Programı buna göre revize edip tekrar maksimum giriş voltajı ile çalıştırınca istediğimiz sonucu alıyoruz.

C++:
#define PIN_ADC0 26

void setup()
{
  pinMode(PIN_ADC0, INPUT);

  analogReadResolution(12);

  Serial.begin(115200);
}

void loop()
{
  while (1)
  {
    int value = analogRead(PIN_ADC0);

    char buffer[20];
    sprintf(buffer, "value = %d\n", value);
    Serial.print(buffer);
    delay(100);
  }
}

Kod:
value = 4093
value = 4080
value = 4082
value = 4086
value = 4085
value = 4085
value = 4080
value = 4079
value = 4074
value = 4073
value = 4083
value = 4077
value = 4091
value = 4080
value = 4083
value = 4084
value = 4080
value = 4095
value = 4082
value = 4080
value = 4079
value = 4080
value = 4082
value = 4085
value = 4091
value = 4080
value = 4081
value = 4078
value = 4079
value = 4083
value = 4083
value = 4083
value = 4083
value = 4080
value = 4083
value = 4079
value = 4080
value = 4082
value = 4083
value = 4085
value = 4083
value = 4083
value = 4080
value = 4084
value = 4082
value = 4078
value = 4082
value = 4081
value = 4081
value = 4080
value = 4083
value = 4085
value = 4082
value = 4080
value = 4081
value = 4077
value = 4081
value = 4088
value = 4083
value = 4078
value = 4082
value = 4095
value = 4083
value = 4086
value = 4080
value = 4081
value = 4081
value = 4095
value = 4082
value = 4083
value = 4066
value = 4083
value = 4082
value = 4084
value = 4080
value = 4086
value = 4036
value = 4082
value = 4080
value = 4083
value = 4081
value = 4082
value = 4085
value = 4083
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
girişe 50 mV gibi düşük bir voltaj değeri verince, ara ara pikler olduğu görülüyor. Bu problem başkaları tarafından da gözlemlenmiş, ve en sonunda üretici de bunu kabullenmiş. Bu problemi dijital sinyal işleme teknikleri ile büyük ölçüde giderebiliriz. Sadece ortalama almak bile büyük fayda sağlar, ama böyle piklerin uzaklaştırılması için başka teknikler de mevcut.


Kod:
value = 84
value = 84
value = 85
value = 38
value = 82
value = 85
value = 84
value = 90
value = 75
value = 82
value = 75
value = 105
value = 85
value = 83
value = 82
value = 77
value = 45
value = 83
value = 82
value = 82
value = 84
value = 83
value = 75
value = 89
value = 83
value = 84
value = 83
value = 84
value = 57
value = 85
value = 82
value = 74
value = 83
value = 83
value = 123
value = 82
value = 81
value = 82
value = 83
value = 84
value = 82
value = 82
value = 81
value = 89
value = 81
value = 84
value = 83
value = 86
value = 84
value = 81
value = 84
value = 83
value = 73
value = 83
value = 95
value = 79
value = 83
value = 85
value = 81
value = 85
value = 83
value = 78
value = 83
value = 82
value = 82
value = 82
value = 81
value = 81
value = 86
value = 84
value = 86
value = 86
value = 86
value = 75
value = 130
value = 84
value = 83
value = 86
value = 82
value = 83
value = 59
value = 34
value = 88
value = 120
value = 87
value = 88
value = 85
value = 82
value = 81
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
ADC okuma sonuçlarını 50 kademeli bir FIR filtreden geçirince piklerden eser kalmıyor.

C++:
#define PIN_ADC0 26

void setup()
{
  pinMode(PIN_ADC0, INPUT);

  analogReadResolution(12);

  Serial.begin(115200);
}

int array[50];

static int run_fir(int data)
{
   unsigned int num_elems = (sizeof(array) / sizeof(array[0]) - 1);

   int sum = 0;
   for (unsigned int i = 1; i <= num_elems; ++i)
   {
      int next = (i < num_elems) ? array[i + 1] : data;
      array[i] = next;
      sum += next;
   }

   return sum / num_elems;
}


void loop()
{
  while (1)
  {
    int value = analogRead(PIN_ADC0);

    char buffer[20];
    sprintf(buffer, "avg = %d\n", run_fir(value));
    Serial.print(buffer);
    delay(100);
  }
}

Kod:
avg = 87
avg = 87
avg = 87
avg = 87
avg = 87
avg = 88
avg = 87
avg = 88
avg = 88
avg = 87
avg = 88
avg = 86
avg = 87
avg = 86
avg = 86
avg = 86
avg = 86
avg = 86
avg = 86
avg = 86
avg = 86
avg = 86
avg = 85
avg = 85
avg = 85
avg = 85
avg = 84
avg = 84
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 86
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 85
avg = 84
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 85
avg = 84
avg = 84
avg = 84
avg = 84
avg = 86
avg = 86
avg = 86
avg = 86
avg = 86
avg = 86
avg = 86
avg = 86
avg = 86
avg = 85
avg = 85
avg = 86
avg = 86
avg = 85
avg = 85
avg = 85
avg = 85
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
avg = 84
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Ama yavaş olan değişkenlik devam ediyor. Bunu engellemek için 3.3 V luk bir voltaj referansı ile denemek lazım. Muhtemelen bu çok büyük bir fark yaratacaktır.
 
Top