Merhaba, aşağıdaki devreyi oluşturdum ır sensörün önünde sabit cisim varken 0rpm gösteriyor. Engeli kaldırdığımda yada motor yardımı ile senkronize döndürdüğümde rakam saçmalıyor sürekli değişiyor bazen - değer gösteriyor.
Bu sorunun üstesinden nasıl gelebilirim acaba?
#include<LiquidCrystal.h>
LiquidCrystal lcd(3,4,5,6,7,8);
float value=0;
float rev=0;
int rpm;
int oldtime=0;
int time;
void isr() //interrupt service routine
{
rev++;
}
void setup()
{
lcd.begin(16,2); //initialize LCD
attachInterrupt(0,isr,RISING); //attaching the interrupt
}
void loop()
{
delay(200);
detachInterrupt(0); //detaches the interrupt
time=millis()-oldtime; //finds the time
rpm=(rev/time)*60000; //calculates rpm
oldtime=millis(); //saves the current time
rev=0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("-AYNA HIZI RPM-");
lcd.setCursor(11,1);
if(rpm>9)lcd.setCursor(10,1);
if(rpm>90)lcd.setCursor(9,1);
if(rpm>900)lcd.setCursor(8,1);
if(rpm>9000)lcd.setCursor(7,1);
if(rpm>90000)lcd.setCursor(6,1);
if(rpm>900000)lcd.setCursor(5,1);
if(rpm>9000000)lcd.setCursor(4,1);
if(rpm>90000000)lcd.setCursor(3,1);
if(rpm>900000000)lcd.setCursor(2,1);
if(rpm>9000000000)lcd.setCursor(1,1);
if(rpm>90000000000)lcd.setCursor(0,1);
lcd.print( rpm);
lcd.print(" rpm");
lcd.print(" ");
attachInterrupt(0,isr,RISING);
}
(https://i.hizliresim.com/om2nvto.PNG)
Şöyle bir ekleme yapayım ır sensörü devreden çıkardım proximity sensör kullandım aynı sorun yine oldu. Hiç sensör kullanmazsam yani nanonun D2 pini boşta kalsa yine aynı sorun oluyor.
Sensör girişini bir dirençle pullup veya pulldown yapmayı deneyin
Sezgin bey sensör girişi derken voltaj girişi mi yoksa ir ledi mi kastediyorsunuz? Sensörü devreden ayırsam yine aynı sorun oluyor sanki kod üzerinde değişiklik yapmak gerekiyor gibi.
Setup kısmının başına
pinMode(D2, INPUT_PULLUP);
satırını ekleyiniz.
Atmel mcularda öntanımlı pin durumu
çıkıştır. D2 giriş olarak tanımlanmalıdır.
Bir devirde kaç sinyal beklentiniz var?
Arduino konusunda yeniyim tecrübem yok yapmamı istediğiniz şu şekildemi acab
void setup()
{
pinMode(D2, INPUT_PULLUP);
lcd.begin(16,2); //initialize LCD
attachInterrupt(0,isr,RISING); //attaching the interrupt
Bir devirde iki sinyal yeterli olur herhalde henüz o kısmın mekaniğini yapmadım bir devirde sensörün önünden engel iki kez geçecek sanıyorum.
Çok düşük devirlerde iki sinyal yetmez.
Bazı durumlarda yüz sinyal bile
yetmiyor.
Yapacağınız işe göre düzenlemelisiniz.
Düşük devirde iki sinyal arasındaki zamanı
ölçmek daha uygun olur.
Yüksek devirlerde de belli süre içinde sinyal
saymak uygun olur.
Bu devreyi mini tornanın ayna devrini ölçmek için kullanacağım. Ayna maksimum 2500 devir, minumum 200 devir dönüyor bu durumda nasıl bir düzenleme yapmalıyım peki
Çamaşır makinesi motorunun devrini 5800'e kadar endüktif Omron sensörle ölçmüştüm. Endüktif sensörün IR sensöre göre kolay tarafı ölçmek istediğiniz mile eşit açılarla mıknatıs yapıtırınca devri istediğiniz katsayı ile ölçebiliyor olmanız. Diğer taraftan vida yapısında olması sebebiyle istenilen yere sabitlenmesi ve yaklaşıp uzaklaşması daha kolay. Bendeki sensör 144Hz yani yaklaşık 8500 sinyal/dk (tek mıknatıs için 8500 devir olarak da düşünebilirsiniz.) okuyordu.
Bence kodun farklı değerler göstermesindeki sebep delay(200) satırı. Bu satırın 200ms de bir tepki vereceği şüpheli. Ben olsam bu kısmı timer içinde sıfırlardım.
İki interrupt kurar birinde sizin yaptığınız gibi external kesme ile sayacı artırır diğerinde saniyede bir veya 2-3 defa timer kesme ile sayacı sıfırlardım. Eğer elinizde skop varsa son haneye kadar kesin okuma yapabilirsiniz.
Şahsen delay komutunun, işlemcinin boş olması durumunda artırım yaparak çalıştığını düşünüyorum. LCD yazma kısmında uzun yada kısa formatta rakam yazılması, bu rutin içinde bölme / floating işlem yapılması cycle bazında da olsa gecikmeye sebep olur. Bu da 200ms sürenin sapması yani 220ms belki 230ms arasında sürmesine sebep olabilir. Sonuçta loop içindeki her if şartı aynı koşullar altında gerçekleşmiyor.
(https://megatekglobal.com/uploads/product/megatekglobal_1639029556.jpg)
Endüktif Sensör (https://www.google.com/search?q=omron+end%C3%BCktif&safe=active&sxsrf=AJOqlzX2__eEhKvPBvKs3-haahE6iza_Yg:1677841914034&source=lnms&tbm=shop&sa=X&ved=2ahUKEwjJw5ma0L_9AhXmQ_EDHfKfBMcQ_AUoAXoECAEQAw&biw=1462&bih=897&dpr=1)
Alıntı yapılan: sezgin05 - 03 Mart 2023, 11:45:37Sensör girişini bir dirençle pullup veya pulldown yapmayı deneyin
Arduino sensör girişi(D2) pinini pullup yapınız. Yada yazılımsal olarak pullup yapabilirsiniz
Alıntı yapılan: fide - 03 Mart 2023, 14:13:12Çamaşır makinesi motorunun devrini 5800'e kadar endüktif Omron sensörle ölçmüştüm. Endüktif sensörün IR sensöre göre kolay tarafı ölçmek istediğiniz mile eşit açılarla mıknatıs yapıtırınca devri istediğiniz katsayı ile ölçebiliyor olmanız. Diğer taraftan vida yapısında olması sebebiyle istenilen yere sabitlenmesi ve yaklaşıp uzaklaşması daha kolay. Bendeki sensör 144Hz yani yaklaşık 8500 sinyal/dk (tek mıknatıs için 8500 devir olarak da düşünebilirsiniz.) okuyordu.
Bence kodun farklı değerler göstermesindeki sebep delay(200) satırı. Bu satırın 200ms de bir tepki vereceği şüpheli. Ben olsam bu kısmı timer içinde sıfırlardım.
İki interrupt kurar birinde sizin yaptığınız gibi external kesme ile sayacı artırır diğerinde saniyede bir veya 2-3 defa timer kesme ile sayacı sıfırlardım. Eğer elinizde skop varsa son haneye kadar kesin okuma yapabilirsiniz.
Şahsen delay komutunun, işlemcinin boş olması durumunda artırım yaparak çalıştığını düşünüyorum. LCD yazma kısmında uzun yada kısa formatta rakam yazılması, bu rutin içinde bölme / floating işlem yapılması cycle bazında da olsa gecikmeye sebep olur. Bu da 200ms sürenin sapması yani 220ms belki 230ms arasında sürmesine sebep olabilir. Sonuçta loop içindeki her if şartı aynı koşullar altında gerçekleşmiyor.
(https://megatekglobal.com/uploads/product/megatekglobal_1639029556.jpg)
Endüktif Sensör (https://www.google.com/search?q=omron+end%C3%BCktif&safe=active&sxsrf=AJOqlzX2__eEhKvPBvKs3-haahE6iza_Yg:1677841914034&source=lnms&tbm=shop&sa=X&ved=2ahUKEwjJw5ma0L_9AhXmQ_EDHfKfBMcQ_AUoAXoECAEQAw&biw=1462&bih=897&dpr=1)
Delay değeri düşük olunca rakamlar çok hızlı değişiyor, değeri arttırırsam arttırdığım kadar rakamların değişimi yavaşlıyor ama benim asıl sorunum devir değerinin atlayarak değişiyor olması. Yani 100 rpm göstermesi gereken değer ekranda 60 oluyor sonra 90 a çıkıyor 115 oluyor sonra tekrar 80 e düşüyor bu şekilde bir tutarsızlık var.
Endüktif sensör ile de denedim sonuç aynı bir şey değişmedi.
Alıntı Yapİki interrupt kurar birinde sizin yaptığınız gibi external kesme ile sayacı artırır diğerinde saniyede bir veya 2-3 defa timer kesme ile sayacı sıfırlardım. Eğer elinizde skop varsa son haneye kadar kesin okuma yapabilirsiniz.
Bu söylediğinizi yapabilecek kadar konuya hakim değilim malesef
03 Mart 2023, 18:57:16Alıntı yapılan: sezgin05 - 03 Mart 2023, 14:30:56Arduino sensör girişi(D2) pinini pullup yapınız. Yada yazılımsal olarak pullup yapabilirsiniz
Malesef buda çözüm olmadı
Elinizde yada erişebileceğiniz bir yerde skop var mı?
Pazartesi gününe kadar imkanım olmaz :du:
Alıntı yapılan: 0M42 - 03 Mart 2023, 20:02:44Pazartesi gününe kadar imkanım olmaz :du:
Loop rutini içinde bir pini toggle yapın ve bu pinin çıktısını skop ile ölçün. Darbe genişliğinin 200ms den fazla olduğunu ve zamanla değiştiğini göreceksiniz.
https://kiritchatterjee.wordpress.com/2014/11/10/a-simple-digital-low-pass-filter-in-c/
Bir filtre kullanabilirsiniz.
Devir olayını hemen hemen hallettim gibi ancak şöyle bir sorunum daha var.
Devreyi enerjilediğimde usb kablosu bilgisayara takılı değilse ekrandaki rpm değeri kendi kendine sürekli değişiyor sensörün önüne sabit bir metal koyarsam 0 oluyor ve öyle kalıyor metali kaldırırsam yine rakamlar değişmeye başlıyor.
Usb kablosu bilgisayara takılıyken ise aynı sorun sensöre yada sensörün kablosuna dokununca oluyor. Sanırım bir tür parazitlenme oluyor bunu nasıl önleyebilirim acaba? (problemi tam olarak anlatamadıysam video ekleyebilirim)
Devrenin gnd si ile, priz toprak pini arasından multimetre kullanarak ac voltaj kademesinde iken ölçüm alın. Eğer 220 volt civarı görüyorsanız, ~2nF 1kv değerinde bir kondansatör bağlantısı yaparak parazitlenmeyi ortadan kaldırma ihtimaliniz var. Yada devrenizi beslediğiniz güç kaynağını değiştirmek, veya güç kaynağının toprak beğlantısını kontrol etmek te sorunu çözme ihtimali doğurabilir.
Hasan bey söylediğinizi yarın deneyeceğim teşekkürler. Yeni farkettiğim şöyle bir durum daha var devre çalışıyorken sensörün gövdesine çıplak el ile dokununca arkasındaki kırmızı led soluk bir şekilde yanıyor. Acaba sensörde mi sorun var bu yüzden mi ekrana değer olarak yansıyor bilemedim malesef elimde başka endüktif sensör de yok.
Ama kablosuna dokununca da ekranda rpm değeri değişiyor buna bir anlam veremedim. Yarın söylediğinizi deneyip sonucu buraya yazacağım.
Alıntı yapılan: hasankara - 05 Mart 2023, 00:29:59Devrenin gnd si ile, priz toprak pini arasından multimetre kullanarak ac voltaj kademesinde iken ölçüm alın. Eğer 220 volt civarı görüyorsanız, ~2nF 1kv değerinde bir kondansatör bağlantısı yaparak parazitlenmeyi ortadan kaldırma ihtimaliniz var.
Ölçümü yaptım hasan bey voltaj görünmüyor. Daha sonra başka bir güç kaynağı ile deneme yaptım, toprak bağlantısınıda gözden geçirdim ama bir değişiklik olmadı sorun devam ediyor.
Kodlarınızı görebilir miyiz?
Tabiki
#include<LiquidCrystal.h>
LiquidCrystal lcd(3,4,5,6,7,8);
volatile uint32_t rev=0;
float rpm;
float rpmx;
uint32_t oldtime=0;
uint32_t newTime;
void isr() //interrupt service routine
{
rev++;
}
void setup()
{
lcd.begin(16,2); //initialize LCD
attachInterrupt(0,isr,RISING); //attaching the interrupt
}
void loop()
{
delay(600); //detaches the interrupt
newTime=millis()-oldtime; //finds the time
rpm=(float(rev)/float(newTime))*60000; //calculates rpm
oldtime=millis(); //saves the current time
rev=0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("-- AYNA HIZI --");
lcd.setCursor(2,1);
byte basamak=0;
while (rpmx>0)
{
rpmx=rpmx/10;
basamak++;
}
lcd.print( rpm);
lcd.print(" d/dk.");
lcd.print(" ");
}
Son durum bu şekilde;
Sensör çıkışının pnp yada npn olmasına göre pull-up yada pulldown gerekebilir. + Besleme ile sensör çıkışı arasına yada sensör çıkışı ile gnd arasına 1k yada 10k ekleyin eğer yoksa.
Npn sensör kullanıyorum çıkışa 10k pull up direnci bağladım (+5 volttan sensör çıkışına) ama değişen bir şey olmadı
Zaman alma mantığınız yanlış.
1000ms hesaplamanız lazım.
Newtime > 1000 olduğu zaman rev değşkeni
sıfırlanıp devir hesaplanmalı.
Elektriksel bir durum yok bence.
D3 hem LCD 'de, hem de kesmede kullanılmış.
Alttaki koda göre pinleri değiştiriniz.
Simülasyonda çalıştırdım.
#include<LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
volatile uint32_t rev = 0;
float rpm;
float rpmx;
uint32_t oldTime = 0;
uint32_t newTime;
void isr(void) //interrupt service routine
{
rev++;
}
void setup(void)
{
Serial.end();
lcd.begin(16, 2); //initialize LCD
pinMode(2, INPUT_PULLUP);
attachInterrupt(0, isr, RISING); //attaching the interrupt "D2"
}
void loop(void)
{
delay(999); //detaches the interrupt
newTime = millis()- oldTime; //finds the time
rpm = (float(rev) / float(newTime)) * 60000; //calculates rpm
rev=0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("-- AYNA HIZI --");
lcd.setCursor(2, 1);
//byte basamak = 0;
//while (rpmx > 0)
//{
// rpmx = rpmx / 10;
// basamak++;
//}
lcd.print( rpm);
lcd.print(" d/dk.");
lcd.print(" ");
oldTime = millis(); //saves the current time
}
İki okuma süresi arasına ekrana yazma süresi de dahil, basamak sayısı değişince bile hata oluşur. Pull up/pull down yoksa kararsız okuma yapar, boştayken kafasına göre değer göstermesi bu yüzden.
Süreyi delay ile değil timer kesmesi ile kontrol edin, timer kesmesi gelince hesaplamaları yapsın, ekrana yazdırılabilir bayrağını set etsin.
Alıntı yapılan: mehmet - 06 Mart 2023, 13:18:52D3 hem LCD 'de, hem de kesmede kullanılmış.
Alttaki koda göre pinleri değiştiriniz.
Simülasyonda çalıştırdım.
#include<LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
volatile uint32_t rev = 0;
float rpm;
float rpmx;
uint32_t oldTime = 0;
uint32_t newTime;
void isr(void) //interrupt service routine
{
rev++;
}
void setup(void)
{
Serial.end();
lcd.begin(16, 2); //initialize LCD
pinMode(2, INPUT_PULLUP);
attachInterrupt(0, isr, RISING); //attaching the interrupt "D2"
}
void loop(void)
{
delay(999); //detaches the interrupt
newTime = millis()- oldTime; //finds the time
rpm = (float(rev) / float(newTime)) * 60000; //calculates rpm
rev=0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("-- AYNA HIZI --");
lcd.setCursor(2, 1);
//byte basamak = 0;
//while (rpmx > 0)
//{
// rpmx = rpmx / 10;
// basamak++;
//}
lcd.print( rpm);
lcd.print(" d/dk.");
lcd.print(" ");
oldTime = millis(); //saves the current time
}
Mehmet bey kodu yükleyip çalıştırdım yine rakamlarda atlama oluyor ama daha az yani atlama aralığı daralmış gibi. Bir de rpm i sanki fazla gösteriyor 100 rpm dönüyorsa 250 gibi gösteriyor. pinMode(2, INPUT_PULLUP); satırı ile pull up eklenmiş oluyor değil mi?
Tam bir şema çıkarmanız mümkün mü?
Besleme ve tüm sinyaller. GND dahil.
Mehmet bey devre her şeyi ile aşağıdaki şemanın aynısı
(https://i.hizliresim.com/3z3ebib.jpg)
Sensörün sarı kablosu ile +5V arasına
1K ekleyin. Zira mcu içindeki pullup
direnci ~50K.
Sensör çıkışı ile +5 volt arası 1k direnç ekledim son durum bu şekilde;
Bazen sabit bir devirde bir süre bekleyince rakamlardaki atlama duruyor devri 15 - 20 sn kadar sabit olarak gösteriyor.
Sonra yine anlık olarak atlama yapıp tekrar sabitleniyor. Ama bu çok nadir oluyor ve o ara devir ile oynarsam yine uzun atlamalar başlıyor.
Öncelikle sensör gövdesini topraklayınız.
Ya da başka bir sensör ile değiştiriniz.
Nasıl bir sensör olur, bilemiyorum.
İkinci olarak benim istediğim noktaya
gelindi: Bir turda tek sinyal almak.
Böylece hassasiyet azalıyor.
Bunun için iki seçenek mevcut.
Biri sinyal sayısının artması.
İkincisi de; bir timer kesmesi ile
çalışan sayaç. Bu sayaç, harici kesmesi
ile devir hesabı yapacak ve sayacı
sıfırlayacak.
Mantığınızı yeniden oluşturun. Ayrıca
hassasiyet durumunuzu da düşünün.
Gerçekten yüzdelik hassasiyete ihtiyacınız
var mı?
Yüzdelik hassasiyete kesinlikle ihtiyacım yok neden o şekilde yola çıktın diye sorarsanız aslında bende bilmiyorum kendiliğinden öyle gelişti gibi bir şey.
Daha önceki söylediğiniz bir turda bir den çok sinyal konusunu şimdi daha iyi anladım. Şu an bir sayıcı kodu üzerinde çalışıyorum öncelikle bir sayaç yapıp sonra o kod üzerinde değişikliğe giderek devir göstergesine dönüştürmeye çalışacağım.
Bilgimde çok kısıtlı daha dün bir bu gün iki o yüzden yazılımda ne isabetli mantık kurabiliyorum nede uygulamaya dökebiliyorum. Gelişmeleri buradan paylaşacağım ilginize çok teşekkür ederim.
Fikir olsun diye söylüyorum. Bu düzenek elimde olsaydı ben şöyle yapardım;
1 adet timer kurardım 1ms'lik.
1 tane de counter kurardım (pulse sayacak)
200 ms olunca counterdan aldığım değeri oranlayıp oran orantı kurarak rpm değerini hesaplardım. Yani bir saniye de 5 kere rpm ölçümü yapıp bu 5 değerin ortalamasını ekrana yazdırırdım. Bu sayede sapma çok daha az olurdu diye düşünüyorum. Tartım yaparkende benzer mantıkla atıyorum 10 adet ölçümün ortalaması ekrana yazdırılıyor. O yüzden tartıdan tam kilogramı okumak için biraz bekletmek gerekiyor ürünü.
Kafamda kurduğum mantık yazdığınıza benzer bir mantık yazdıklarınızı da dikkate alacağım Selehaddin bey teşekkür ederim