Witam, mam problem dotyczący zliczania obrotów czujnikiem halla w arduino. Mam kod który to robi ale jest jeden problem a mianowicie na monitorze portu szeregowego podawane są wartości co 1200 impulsów czyli 1200, 2400, 3600 i tak dalej zamiast normalnie. Kod mam z internetu i ktoś kto to zrobił miał "normalnie" ale u mnie tak niestety nie jest. Czy można to jakoś naprawić ? Z góry dziękuję za pomoc.
Kod:
#include <Wire.h>
const int hallSensorPin = 2;
const unsigned long sampleTime = 50;
const int maxRPM = 14000;
int rpmMaximum = 0;
void setup()
{
pinMode(hallSensorPin,INPUT);
Serial.begin(9600);
}
void loop()
{
delay (350);
int rpm = getRPM();
if (rpm > rpmMaximum) rpmMaximum = rpm;
displayRPM(rpm);
displayBar(rpm);
}
int getRPM()
{
int count = 0;
boolean countFlag = LOW;
unsigned long currentTime = 0;
unsigned long startTime = millis();
while (currentTime <= sampleTime)
{
if (digitalRead(hallSensorPin) == HIGH)
{
countFlag = HIGH;
}
if (digitalRead(hallSensorPin) == LOW && countFlag == HIGH)
{
count++;
countFlag=LOW;
}
currentTime = millis() - startTime;
}
int countRpm = int(60000/float(sampleTime))*count;
return countRpm;
}
void displayRPM(int rpm)
{
Serial.print(rpm);
Serial.println("|");
}
void displayBar(int rpm)
{
int numOfBars=map(rpm,0,maxRPM,0,15);
if (rpm!=0)
{
for (int i=rpm; i<=numOfBars; i++)
{}
}
}
(11-06-2024, 23:45)poziomka97 napisał(a): [ -> ]Witam, mam problem dotyczący zliczania obrotów czujnikiem halla w arduino. Mam kod który to robi ale jest jeden problem a mianowicie na monitorze portu szeregowego podawane są wartości co 1200 impulsów czyli 1200, 2400, 3600 i tak dalej zamiast normalnie. Kod mam z internetu i ktoś kto to zrobił miał "normalnie" ale u mnie tak niestety nie jest. Czy można to jakoś naprawić ? Z góry dziękuję za pomoc.
Czysta matematyka - liczysz (a więc liczby całkowite) impulsy w czasie 50ms - 1/20 sekundy. Stąd 1 zliczony impuls odpowiada 1200 (20 * 60) obr/min, 2 - 2400 obt/min itp. Po prostu tyle wynosi rozdzielczość pomiaru.
To w sumie jest pomiar częstotliwości - a częstotliwość mierzy się zasadniczo na 2 sposoby - duże częstotliwości mierzy się jak tutaj - w ustalonym czasie liczy się impulsy, a małe mierząc czas jaki upływa pomiędzy dwoma impulsami. Musisz zwiększyć czas czas w jakim impulsy są liczone - to zmienna sampleTime w twoim kodzie.
Można też umieścić więcej magnesików - tak by 1 obrót dawał kilka impulsów.
(12-06-2024, 00:06)oscarX napisał(a): [ -> ] (11-06-2024, 23:45)poziomka97 napisał(a): [ -> ]Witam, mam problem dotyczący zliczania obrotów czujnikiem halla w arduino. Mam kod który to robi ale jest jeden problem a mianowicie na monitorze portu szeregowego podawane są wartości co 1200 impulsów czyli 1200, 2400, 3600 i tak dalej zamiast normalnie. Kod mam z internetu i ktoś kto to zrobił miał "normalnie" ale u mnie tak niestety nie jest. Czy można to jakoś naprawić ? Z góry dziękuję za pomoc.
Czysta matematyka - liczysz (a więc liczby całkowite) impulsy w czasie 50ms - 1/20 sekundy. Stąd 1 zliczony impuls odpowiada 1200 (20 * 60) obr/min, 2 - 2400 obt/min itp. Po prostu tyle wynosi rozdzielczość pomiaru.
To w sumie jest pomiar częstotliwości - a częstotliwość mierzy się zasadniczo na 2 sposoby - duże częstotliwości mierzy się jak tutaj - w ustalonym czasie liczy się impulsy, a małe mierząc czas jaki upływa pomiędzy dwoma impulsami. Musisz zwiększyć czas czas w jakim impulsy są liczone - to zmienna sampleTime w twoim kodzie.
Można też umieścić więcej magnesików - tak by 1 obrót dawał kilka impulsów.
No dobra działa ale wystąpił kolejny problem. Po zwiększeniu tego czas wydłużyło się też wyświetlanie danych w porcie bo ustawiłem tam 720 ms bo tyle jest potrzebne do uzyskania odpowiednich wartości a zależy mi na tym aby opóźnienie nie występowało w ogóle i wszystko było w czasie rzeczywistym. Może można na tych 50 ms zrobić jakieś inne obliczenie i już nawet zwiększyć maksymalną wartość ? Nie muszą to być dokładne wartości, ważne żeby były w miarę szybko.
Do takich rzeczy służą timery i icp wtedy było by normalnie i szybko i bez blokad i wyświetlanie nie czasie rzeczywistym.
(12-06-2024, 08:59)Jarewa0606 napisał(a): [ -> ]Do takich rzeczy służą timery i icp wtedy było by normalnie i szybko i bez blokad i wyświetlanie nie czasie rzeczywistym.
A można to wpisać w kod czy potrzebne są jakieś inne przyrządy ? Bo jeżeli sam kod to lepiej ale i tak nie potrafię tego napisać

(
Mam pomysł. A jakby tak z tego kodu wyrzucić funkcje obliczenia RPM i zostawić "gołe" impulsy, które będę miał od razu bo tylko to potrzebuje. Wartość RPM w zasadzie nie jest mi do niczego potrzebna. Dobrze myślę ?
Po prostu wyrzucę to:
Kod:
int countRpm = int(60000/float(sampleTime))*count;
return countRpm;
Przyjże się bo mam projekt na atinny i oleda pomiar prędkości wrzeciona to jak będzie do przeróbki to vi wrzucę zapodam wieczorem.
(12-06-2024, 10:44)poziomka97 napisał(a): [ -> ]Mam pomysł. A jakby tak z tego kodu wyrzucić funkcje obliczenia RPM i zostawić "gołe" impulsy, które będę miał od razu bo tylko to potrzebuje. Wartość RPM w zasadzie nie jest mi do niczego potrzebna. Dobrze myślę ?
Po prostu wyrzucę to:
Kod:
int countRpm = int(60000/float(sampleTime))*count;
return countRpm;
Ten fragment kodu jest trochę dziwnie napisany, ale nie on decyduje o czasie trwania. Pojedyncze obliczenia zmiennoprzecinkowe, nawet na małym 8-bitowcu zużyją może milisekundę.
Użycie ICP jest zdecydowanie najlepszym rozwiązaniem - przede wszystkim przechodzimy na tą drugą metodę pomiaru częstotliwości - przez pomiar okresu - wystarczy jeden obrót by otrzymać wynik. Jednak wtedy nie wiadomo ile potrwa taki pomiar bo jak obroty będą małe może to być nawet kilkukrotnie więcej niż 50ms. 1200 obr/min to 20obr/sec czyli 20 pomiarów na sec - minimalnie to 50ms na pomiar. Zaletą ICP jest fakt, że nie musisz zatrzymywać kodu na czas pomiaru - robote zrobią timery. Wadą - zależnie od typu procka prawdziwe ICP to jedna/kilka konkretna nóżka procka - a więc być może trzeba będzie zmienić połączenia. Np.w ATXmegach można było użyć dowolnego pinu jako ICP.
Już sugerowałem użycie drugiego magnesika lub hallotronu. Można pójść dalej i dać więcej, można też też zrobić odczyt optyczny i tarczę z paskami/szczelinami. Nawet można namalować paski na wale. Taką tarczę można zrobić z kliszy fotograficznej - robiąć zdjęcie powiększonemu obrazkowi, wywołując kliszę i wycinając odpowiednie kółko. Przydałby się aparat na duży obrazek 6x6. Sam się trochę zdziwiłem, jak podczas rozbierania drukarki zauważyłem, że napędzana jest nie silnikami krokowymi, a zwykłymi szczotkowymi, ale każdy ma na osi bardzo gęstą tarczę z paskami, umożliwiającą odczyt ze 100 kroków na obrót. To taki odpowiednik przekładni. Taki mechanizm, tylko trochę mniej czuły był stosowany w starych myszkach - takich z kólką, która toczyła się po stole. Była tam zwykle mała (ok 1cm) tarcza ze szczelinami i odpowiednie transoptory szczelinowe.
W ten sposób możesz poprawić dokładność i/lub czas pomiaru.
(13-06-2024, 16:00)oscarX napisał(a): [ -> ] (12-06-2024, 10:44)poziomka97 napisał(a): [ -> ]Mam pomysł. A jakby tak z tego kodu wyrzucić funkcje obliczenia RPM i zostawić "gołe" impulsy, które będę miał od razu bo tylko to potrzebuje. Wartość RPM w zasadzie nie jest mi do niczego potrzebna. Dobrze myślę ?
Po prostu wyrzucę to:
Kod:
int countRpm = int(60000/float(sampleTime))*count;
return countRpm;
Ten fragment kodu jest trochę dziwnie napisany, ale nie on decyduje o czasie trwania. Pojedyncze obliczenia zmiennoprzecinkowe, nawet na małym 8-bitowcu zużyją może milisekundę.
Użycie ICP jest zdecydowanie najlepszym rozwiązaniem - przede wszystkim przechodzimy na tą drugą metodę pomiaru częstotliwości - przez pomiar okresu - wystarczy jeden obrót by otrzymać wynik. Jednak wtedy nie wiadomo ile potrwa taki pomiar bo jak obroty będą małe może to być nawet kilkukrotnie więcej niż 50ms. 1200 obr/min to 20obr/sec czyli 20 pomiarów na sec - minimalnie to 50ms na pomiar. Zaletą ICP jest fakt, że nie musisz zatrzymywać kodu na czas pomiaru - robote zrobią timery. Wadą - zależnie od typu procka prawdziwe ICP to jedna/kilka konkretna nóżka procka - a więc być może trzeba będzie zmienić połączenia. Np.w ATXmegach można było użyć dowolnego pinu jako ICP.
Już sugerowałem użycie drugiego magnesika lub hallotronu. Można pójść dalej i dać więcej, można też też zrobić odczyt optyczny i tarczę z paskami/szczelinami. Nawet można namalować paski na wale. Taką tarczę można zrobić z kliszy fotograficznej - robiąć zdjęcie powiększonemu obrazkowi, wywołując kliszę i wycinając odpowiednie kółko. Przydałby się aparat na duży obrazek 6x6. Sam się trochę zdziwiłem, jak podczas rozbierania drukarki zauważyłem, że napędzana jest nie silnikami krokowymi, a zwykłymi szczotkowymi, ale każdy ma na osi bardzo gęstą tarczę z paskami, umożliwiającą odczyt ze 100 kroków na obrót. To taki odpowiednik przekładni. Taki mechanizm, tylko trochę mniej czuły był stosowany w starych myszkach - takich z kólką, która toczyła się po stole. Była tam zwykle mała (ok 1cm) tarcza ze szczelinami i odpowiednie transoptory szczelinowe.
W ten sposób możesz poprawić dokładność i/lub czas pomiaru.
Generalnie chodzi o to że podpinam arduino pod czujnik obrotów (kabelki podpięte do licznika) w motocyklu. Ten kod który mam działa lecz co 1200 jednostek. Oczywiście aby wykonać jakąś blokadę obrotów (używając przekaźnika wpiętego w czujnik stópki) to wystarczy. Natomiast wymyśliłem licznik cyfrowy z telefonu na androidzie do którego mam zrobioną aplikację w APP Inventorze. Tam do wpisania mam bardzo dokładne wartości bez opóźnień których nie mogę jak narazie uzyskać z portu szeregowego a pomysł z ICP wydaje się sensowny z tym że nie wiem jak mam się do tego zabrać i nawet nie znalazłem żadnych przykładów a z pisaniem tego może być u mnie dosyć spory problem.
Jaki masz uc bo jednak jest różnica z atinny