Touchless rotary encoder.

Posted: 26 Januari 2014 in Otomasi dan Robotika
Tag:,

Eksperimen

Eksperimen

Wah habis eksperimen, jadi idenya bikin game sepeda pancal. kita maen game sekaligus olah raga. sistem ini pakai ngirim derajat kemudi, rem dan kecepatan. seru juga he he he …. ya nanti deh di update jika game nya udah jadi dan saya posting deh…

di awal saja deh kesimpulannya

jadi ini kesimpulan yang didapat

  1. Arduino duemilanove cukup mampu untuk menghitung kecepatan putar motor. tentu ada batasnya. kan tiap siklus clock mikrokontroller bisa saja lebih lambat dari kecepatan putar motor. perlu diingat It takes about 100 microseconds (0.0001 s) to read an analog input, so the maximum reading rate is about 10,000 times a second. (diambil dari reference nya analogRead Arduino) . ADC memiliki keterbatasan baca. selama percobaan sih sepertinya motornya masih lebih lambat daripada Arduino sehingga masih bisa dibaca. Dalam percobaan ini motor berputar sekitar 60 rps. (rotation per second).= 3600 rpm. Format data yang dikirimkan. kirim = (String)derajatKemudi()+”#”+Rem()+”#”+kecepatanMperSecond+”#”+digitalRead(A2)+”#”+rps+”#”+countBaling+”#”+countBalingtest;

    Hasil pengiriman data

    Hasil pengiriman data

  2. menggunakan Library EEPROMex. karena menyimpan data integer yang berukuran 2 byte. (library defaultnya hanya bisa 1 byte).
  3. encoder semacam ini sensitif terhadap CPU Time. sehingga bila Mikrokontroller melakukan tugas yang banyak dan terdelay kemungkinan akan mempengaruhi hasil perhitungan encoder. oleh karena itu ini saya buat sesimple mungkin untuk mikrokontroller… dan tidak saya beri delay sama sekali
    schema

    schema menggunakan fritizing

    encoder

    motor

    motor

    Hasil akhir game sepeda yang ingin dicapai.

hasil akhir yang ingin dicapai

hasil akhir yang ingin dicapai

=======================================START OF SOURCE CODE=================================================================

#include EEPROMex.h

const double kelilingRoda = 1.5; //Meter
const int waktuSampling = 250;//milisekon,
//waktuSampling tidak mempengaruhi kecepatan, hanya pengiriman datanya lebih cepat lebih responsif
const byte jmlBaling = 8; //jumlah baling putih saja artinya nanti menghasilkan 8 pulsa / putaran atau 20p/r

String kirim;
char mode;
unsigned int lowIn, highIn, lowRem,highRem, batasBlackWhite = 0;

void setup()
{

  pinMode(A2, INPUT);
  pinMode(13, OUTPUT);
  Serial.begin(9600);

  //load nilai tersimpan pada EEPROM karena int 2 byte maka jangkah 2-2
  lowIn=EEPROM.readInt(0);
  highIn=EEPROM.readInt(2);
  batasBlackWhite=EEPROM.read(4);
  lowRem=EEPROM.readInt(6);
  highRem=EEPROM.readInt(8);
  mode=EEPROM.read(10);//1 byte
}

void loop()
{

  bacaPerintah();
  hitungKecepatan();

}

double derajatKemudi()
{
	//range setir -90 s/d 90 = 180
	int valueIn = analogRead(A0);
	double derajat=-90 +(valueIn-lowIn)*(180.00/(highIn-lowIn));
	//pembacaan akan eror nilainya jika derajat setir lebih dari batas yang ditentukan -90 sampai 90
	//di paskan
	if(valueIn<lowIn)
		derajat = -90.00;
	else if(valueIn>highIn)
		derajat = 90.00;

	return derajat;
}
double Rem()
{
	//range rem 0-9.
	int valueIn = analogRead(A3);
	double rem=0.0 +(valueIn-lowRem)*(9.00/(highRem-lowRem));
	if(valueIn<lowRem)
		rem = 0.00;
	else if(valueIn>highRem)
		rem = 9.00;

	return rem;
}

void hitungKecepatan()
{
   static unsigned int countBaling,countBalingtest;
   static unsigned long lastTime;
   static boolean statKec1, statKec2;
  //countBalingtest hanya digunakan untuk kalibrasi jumlah pulsa 1 putaran penuh.
  //jika sudah dikalibrasi tidak perlu di kirim ke serial
  unsigned int analogKec=analogRead(A1);
  if(analogKec<batasBlackWhite) //analog dijadikan digital
  {
	  statKec1=HIGH;
      digitalWrite(13, HIGH); //menyalakan led internal arduino agar terlihat beda sense hitam putih
  }
  else
  {
	  statKec1=LOW;
	  digitalWrite(13, LOW);
  }
  //togle bila kondisi tidak sama dengan sebelumnya maka hitung
  //bila sama maka sensor masih menghitung salah satu hitam atau putih dan belum berubah

  if(statKec2!=statKec1)
  {
	if( statKec1==HIGH)//rising .. dari lowh menjadi high yg dihitung. kalau high jadi low tidak dihitung.
	{
		countBaling++;
		countBalingtest++;
	}
    statKec2=statKec1;
  }

  if(millis()-lastTime>= waktuSampling )/*waktuSampling diganti dengan 1000 = 1 detik*/
  {
	//rps = rotation per second.
    double rps=((double)countBaling/jmlBaling)*(1000.0/waktuSampling);
	double kecepatanMperSecond = rps * kelilingRoda;

	//timer setelah hitung kecepatan putar selama >= waktu sampling lalu kirim
	//derajat kemudi # rem # kecepatanMperSecond # mundur  # countBaling # countBalingtest
	//untuk yang rem mirip dengan derajat kemudi. tinggal gunakan variable yang beda
	//perlu diingat karena arduino sangat "terbatas" maka gunakan variable sehemat mungkin.
	//gunakan tipe data yang tepat
	//A2 = tombol jalan mundur
	//count baling cuma buat coba2 bisa ngukur beda di kertas putih n hitam
	//countBalingtest cuma buat coba2 jumlah pulsa yang dihasilkan selama running mikrokontroller
	//usahakan pengiriman data seminimal mungkin
	//countBaling = jumlah pulsa yang dihasilkan baling dalam waktu sampling
	//countBalingtest = jumlah pulsa mulai dari hidup

	//mode pengiriman data
	if(mode=='D')//debug mode
	{
	    unsigned long runningTime = millis();
		kirim = (String)derajatKemudi()+"#"+Rem()+"#"+kecepatanMperSecond+"#"+digitalRead(A2)+"#"+rps+"#"+countBaling+"#"+countBalingtest+"#"+(runningTime/1000)/3600+" hours "+((runningTime/1000)/60)%60 +" minutes "+(runningTime/1000)%60+" seconds" ;

	}
	else if(mode=='R')//running mode
	{
		kirim = (String)derajatKemudi()+"#"+Rem()+"#"+kecepatanMperSecond+"#"+digitalRead(A2);
	}
	else
	{
		kirim = "info#Please set send mode fisrt";
	}

    Serial.println(kirim);
	countBaling = 0;
      lastTime=millis();
  }

}

void bacaPerintah()
{
	static unsigned int batasAnalogWhite;
	if (Serial.available()>0)
	{
		char perintah = Serial.read();

		//FYI EEPROM AVR memiliki batas tulis 100 ribu kali.
		//jadi jangan terlalu sering di write.
		if(perintah=='a')//kalibrasi lowIn (-90 derajat)
		{
			  lowIn = analogRead(A0);
			  //masukkan lowIn ke EEPROM;
			  if(EEPROM.updateInt(0, lowIn))
			  {
				  //diberi info# untuk membedakan header data sensor atau informasi.
				  //tinggal diberi if di unity
				  kirim = (String)"info#Analaog value "+lowIn+" as -90 calibration";
				  Serial.println(kirim);
			  }
		}
		else if(perintah=='b')//kalibrasi highIn (90 derajat)
		{
			  highIn = analogRead(A0);
			  //masukkan highIn ke EEPROM;
			  if(EEPROM.updateInt(2, highIn))
			  {
					kirim = (String)"info#Analaog value "+highIn+" as 90 calibration";
					Serial.println(kirim);
			  }
		}
		else if(perintah=='c')
		{
			batasAnalogWhite =  analogRead(A1);
			kirim = (String)"info#Analaog value "+batasAnalogWhite+" as white calibration";
			Serial.println(kirim);
		}
		else if(perintah=='d')
		{
			int batasAnalogBlack =  analogRead(A1);
			kirim = (String)"info#Analaog value "+batasAnalogBlack+" as black calibration";
			Serial.println(kirim);
			batasBlackWhite = (int)(batasAnalogBlack - batasAnalogWhite)/2; // batas tengah antara black white
			if(EEPROM.updateInt(4, batasBlackWhite))
			  {
					kirim = (String)"info#Analaog value "+batasBlackWhite+" as batasBlackWhite calibration";
					Serial.println(kirim);
			  }
		}
		else if(perintah=='e')//kalibrasi lowRem (tidak ngerem)
		{
			  lowRem = analogRead(A3);
			  //masukkan lowIn ke EEPROM;

			  if(EEPROM.updateInt(6, lowRem))
			  {
					kirim = (String)"info#Analaog value "+lowRem+" as lowRem calibration";
					Serial.println(kirim);
			  }
		}
		else if(perintah=='f')//kalibrasi highRem (sangat ngerem)
		{
			  highRem = analogRead(A3);
			  //masukkan highIn ke EEPROM;
			  if(EEPROM.updateInt(8, highRem))
			  {
					kirim = (String)"info#Analaog value "+highRem+" as highRem calibration";
					Serial.println(kirim);
			  }
		}
		else if(perintah=='g')//set debug mode
		{
			  mode='D';
			  if(EEPROM.update(10, mode))
			  {
					kirim = (String)"info#Data send mode "+mode;
					Serial.println(kirim);
			  }
		}
		else if(perintah=='h')//running mode
		{
			  mode='R';
			  if(EEPROM.update(10, mode))
			  {
					kirim = (String)"info#Data send mode "+mode;
					Serial.println(kirim);
			  }
		}
	}
}

=======================================END OF SOURCE CODE==================================================================

About these ads
Komentar
  1. […] shared with us his project about a touchless rotary encoder made with Arduino Duemilanove able to count rounds per […]

  2. […] shared with us his project about a touchless rotary encoder made with Arduino Duemilanove able to count rounds per […]

  3. […] shared with us his project about a touchless rotary encoder made with Arduino Duemilanove able to count rounds per […]

Tinggalkan Balasan

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Logout / Ubah )

Twitter picture

You are commenting using your Twitter account. Logout / Ubah )

Facebook photo

You are commenting using your Facebook account. Logout / Ubah )

Google+ photo

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s