Arduino da kodun gecikmeli çalışması hakkında

Başlatan overlok, 13 Aralık 2020, 11:53:21

overlok

Merhaba; bundan 1 ay kadar önce deneme yaptığım kod o zaman normal çalışırken, dün yaptığım denemede yavaş çalışmaya başladı.

Şöyleki; 2,4 ghz rc araç kumandasından gelen sinyale göre Arduino pro mini ile servo motor ve led kontrolü yapmaya çalışıyorum. Ayrıca ntc ile ısı ölçümü yapıp duruma göre işlem yaptırıyorum. Aynı Arduino ile 1 ay kadar önce ilk denemeyi yaptığımda gayet düzgün çalışıyordu. Yani mesela devredeki servo motor gayet akıcı şekilde belirlediğim açı aralığında dönüyordu.

Dün akşam denemelerimde servo saniye gibi tık tık yaparak dönmeye başladı. Led, servo motorun son konuma geldiğinde yanması gerekiyor. Servo motor gecikmeli döndüğü için de led daha geç yanıyor haliyle.
Sanki programda delay komutunun değeri arttırılmış gibi.

Bu arada Arduino nano ile de denedim sonuç aynı. Başka pc'den de programladım değişmedi.

Aynı Arduino'ya daha sonra başka kodlar da yüklemiştim. Bilmeden bi ayarla falan mı oynadım yada değiştirdim acaba? Veya arada yüklediğim kodlarda Arduino'nun bootloader'ını veya saat frekansını etkileyen kodlar olabilir mi?
Mesela en son RTC modül, oled ekran, dht 11 ile saat kodu yüklemiştim diye hatırlıyorum aynı Arduino Pro Mini'ye ve Nano'ya.
Böyle bir şey ile karşılaşan oldu mu?
1 ay kadar önce normal çalışan kod bugün niye gecikmeli çalışır?

Kodlar birkaç kodun birleşimi ve arada benim eklediğim yerler var.

#include <Servo.h>
Servo myservo;


int sinyal;
int angle = 80;    // initial angle  for servo
int angleStep = 40;
#define far 12
#define led 11
#define led1 10
#define led2 8

 

 void setup(){
  myservo.attach(9);
 pinMode(2, INPUT);
 pinMode(3, INPUT);
 pinMode(4, INPUT);
 pinMode(8, OUTPUT);
 pinMode(10, OUTPUT);
 pinMode(11, OUTPUT);
 pinMode(12, OUTPUT);
 Serial.begin(9600);
 }


double Termistor(int analogOkuma){

 double sicaklik;
 sicaklik = log(((10240000 / analogOkuma) - 10000));
 sicaklik = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * sicaklik * sicaklik)) * sicaklik);
 sicaklik = sicaklik - 273.15;
 return sicaklik;
 

 
 }
 void loop(){
  sinyal=pulseIn(3,HIGH);
if (sinyal>1500) {
 
  if (angle > 79 && angle <= 180) {
      angle = angle - angleStep;
      if(angle < 79){
        angle = 80;
        digitalWrite(far, HIGH);
      
      }else{
      myservo.write(angle);
Serial.println(sinyal);
      
       }}
delay(50);
 }
 if(sinyal<1500){
  digitalWrite(far, LOW);
  if (angle >= 80 && angle <= 180) {
      angle = angle + angleStep;
      if(angle > 180){
        angle = 180;
       
       }else{
      myservo.write(angle);
    Serial.println(sinyal);
 }}
  delay(50); // waits for the servo to get there
  }
  
  sinyal=pulseIn(2,HIGH);
if (sinyal<1500) {
  digitalWrite(led, HIGH);
        }else{
      digitalWrite(led, LOW);
Serial.println(sinyal);
       }
       int deger = analogRead(A1);
  double sicaklik = Termistor(deger);
  Serial.println(sicaklik);

  if(sicaklik > 60){
    digitalWrite(led2,HIGH);
  }
  else{
    digitalWrite(led2,LOW);
delay(50);
 
 } }
Hanımların dikkatine, overlok makinesi ayağınıza geldi!

mg1980

Aynı Timer'i aynı anda kullanan kütüphaneler varsa bundan olabilir.

selimkoc

Seri haberleşme hızını arttırabilirsin. Bir de digitalWrite ve digitalRead yerine avr programlama yapabilirsin.

https://elektrokod.wordpress.com/2020/03/29/arduino-derleyiciniz-ne-kadar-hizli/

overlok

Alıcıdan Arduino'ya bağlantının birini yapmamıştım. Sadece servo bağlantısını yapmıştım. Böyle çalıştığında yavaş kalıyor. Diğer bağlantıyı da yapınca kod normal calışıyor.
Diğer bağlantı dediğimde kodun şu kısmı:

sinyal=pulseIn(2,HIGH);
if (sinyal<1500) {
  digitalWrite(led, HIGH);
        }else{
      digitalWrite(led, LOW);
Serial.println(sinyal);
Hanımların dikkatine, overlok makinesi ayağınıza geldi!

sinus

Boş bir mcu'ya Arduino bootloader atınca kod başlangıçta 1sn gecikmeli çalışıyordu. Ona benzer bir durum olabilir.

İDE güncelleme almış olabilir. Bazı sürümlerde düzgünce derlenen/yüklenen kod üst sürümlerde problem çıkartabiliyor.

overlok

İlgili pin'i boş bırakınca sanırım kod düzgün çalışmıyor. Yada benim kodların yazım şekli hatalı.
Hanımların dikkatine, overlok makinesi ayağınıza geldi!

muhendisbey

#6
Kodu optimize etmen gerekli olduğunu düşünüyorum. Kodunda if şartına giren iki farklı sinyal<1500 durumu var. Bu iki şartı birleştirmen işlem hızı açısından zaman kazandırır.
Bir diğeri sinyalin tam 1500 olduğu durum. Kodun nerede başlayıp nerede bittiğini buradan direk göremiyorum ama pulseIn ve analogread komutları arasında jet hızında bir geçiş sözkonusu. Böyle bir durum olmasını istediğin bir durum mudur? Bu durum devrene bağlı ama hatırlatmak istedim.
Tek bir ADC okumasına güvenmemeni tavsiye ederim. Çoklu okuma yapmak daha garantilidir.

Bir diğeri uzay bağlantısı. Eğer uzay bağlantısı yapılarak kurulmuşsa devreler, parazitlerden etkilenir. Bu parazitler seri iletişimden gelen kodun içerisinde sanki fazladan kodmuş gibi görünebilir.

Atıyorum: gönderdiğin kod "z1500"
Karşıya giden ^+%^%&^z1500'^+'^+'

Yazılımsal olarak kod sürekli olarak varsa ve bir okuma beklentisi varsa bu parazit ne kadar uzarsa o kadar gecikmeli çalışır. Uzay bağlantı ile çalışılacaksa iyi bir besleme olması ya da faraday kafesinde olması, ya da kabloların blendajlı olması gerekir ki parazitten en az etkilensin.

Şöyle bir deneme yapabilirsin. Kafesi sökülmüş bir güç kaynağı ya da bir trafo yakınında devren nasıl çalışıyor? Normalde nasıl çalışıyor?

Boşta pin bırakmak hatalıdır. Hele de kullanılan bir modül varsa (serial 0 modülü mesela) hatalı çalışmaya neden olabilir.
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.

overlok

Alıntı yapılan: muhendisbey - 14 Aralık 2020, 09:54:32Kodu optimize etmen gerekli olduğunu düşünüyorum. Kodunda if şartına giren iki farklı sinyal<1500 durumu var. Bu iki şartı birleştirmen işlem hızı açısından zaman kazandırır.
Bir diğeri sinyalin tam 1500 olduğu durum. Kodun nerede başlayıp nerede bittiğini buradan direk göremiyorum ama pulseIn ve analogread komutları arasında jet hızında bir geçiş sözkonusu. Böyle bir durum olmasını istediğin bir durum mudur? Bu durum devrene bağlı ama hatırlatmak istedim.
Tek bir ADC okumasına güvenmemeni tavsiye ederim. Çoklu okuma yapmak daha garantilidir.

Bir diğeri uzay bağlantısı. Eğer uzay bağlantısı yapılarak kurulmuşsa devreler, parazitlerden etkilenir. Bu parazitler seri iletişimden gelen kodun içerisinde sanki fazladan kodmuş gibi görünebilir.

Atıyorum: gönderdiğin kod "z1500"
Karşıya giden ^+%^%&^z1500'^+'^+'

Yazılımsal olarak kod sürekli olarak varsa ve bir okuma beklentisi varsa bu parazit ne kadar uzarsa o kadar gecikmeli çalışır. Uzay bağlantı ile çalışılacaksa iyi bir besleme olması ya da faraday kafesinde olması, ya da kabloların blendajlı olması gerekir ki parazitten en az etkilensin.

Şöyle bir deneme yapabilirsin. Kafesi sökülmüş bir güç kaynağı ya da bir trafo yakınında devren nasıl çalışıyor? Normalde nasıl çalışıyor?

Boşta pin bırakmak hatalıdır. Hele de kullanılan bir modül varsa (serial 0 modülü mesela) hatalı çalışmaya neden olabilir.

Evet hocam kodları daha düzgün yazmam gerekiyor. Parazit konusunu dikkate alacam. Zira devrenin yakınında fırçası motor çalışıyor olacak. Rc araç içine yerleştirecem bu devreyi.

Kumandandan gelen sinyal, tuşun konumuna göre 1000 veya 1900. Arası olmuyor gördüğüm.

Pulsin ve analogread bunu farketmemisim hiç. Yani hızlı geçişi. Kontrol edeyim onuda.

Uzay baglanti dediğiniz kablo ile arada mesafe ile mi baglantı? Öyle ise evet kablolara da önlem alayım.
Hanımların dikkatine, overlok makinesi ayağınıza geldi!

brandice5

https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/

pulseIn fonksiyonuna timeout parametresi vermemissin. Dolayisiyla bu pini bos birakirsan her okumada default deger olan 1 saniye kadar pulseIn satirinda bekler.

Ya pini bos birakmayacaksin, ya da pulseIn fonksiyonuna ucuncu parametre olarak daha dusuk bir timeout degeri gir.

pulseIn(2,HIGH, 10000); gibi (en fazla 10ms bekler)

muhendisbey

Alıntı yapılan: overlok - 14 Aralık 2020, 10:45:39Kumandandan gelen sinyal, tuşun konumuna göre 1000 veya 1900. Arası olmuyor gördüğüm.

Uzay baglanti dediğiniz kablo ile arada mesafe ile mi baglantı? Öyle ise evet kablolara da önlem alayım.

Göreceğin değeri bu durumda 100 kadar eşik belirleyip if şartlarını 1100'den küçük, else if 1800'den büyük yapabilirsin. İşlemi bitirmek için değişkene 1500 gibi hiç görülmemiş ara değer atayabilirsin. Böylece koşulların sadeleşmiş olur. Hatta bu değerler için tekrar tekrar programlamak yerine dahili eeprom'da tutturabilirsin. İleride kalibre etmen gerekirse kodlamadan seri'den göndereceğin birkaç komut ile eeprom'a kaydedip sonrasında eepromdan okuyarak eşik değerlerini ayarlarsın.

Uzay bağlantıdan kastım dediğiniz gibi kablolu bağlantı. Böyle bağlantılar olduğunda flüoresan lambadan dahi etkilenebilir olur. Kablo uzunluğuna bağlı olarak etkilenme miktarı değişir. Anten gibi davranır ve çevredeki elektromanyetik dalgaları almış olur. Yapılan işe göre sırf bunun olmaması ya da en aza inmesi için çıkışlarda PC817 optokuplör kullanırım. Girişlerde de eğer data değil de buton vari işlerse yine optokuplörü tersten kullanırım.
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.