vibration sensor use as a switch help!

Thread Starter

gatoulisss

Joined Jan 23, 2015
55
hello everyone! I want your help!

im using a pic16f88 microcontroller with 5v and I want to "read" a vibration sensor like a switch. for example if the sensor moves then I take as input to mcu '1' if ts steady then I take' 0'.
my problem is that when I shake the sensor the voltage is between 1v to 4v so the input is not always '1'.

is there any way to fix that? so when there is shake or vibration the input of mcu it will be '1'until the vibration stops

thank you very much!
 

djsfantasi

Joined Apr 11, 2010
5,704
So connect the sensor to an analog pin. Experimentally determine a threshold. Use that to determine what to use to set a 1 or 0. Or true or false. I’m presupposing that your PIC has st least one analog input.
 

Thread Starter

gatoulisss

Joined Jan 23, 2015
55
So connect the sensor to an analog pin. Experimentally determine a threshold. Use that to determine what to use to set a 1 or 0. Or true or false. I’m presupposing that your PIC has st least one analog input.
Yes it has analog inputs
So you mean that doing this is like measuring input voltage and decide in which values my input is ‘1’ and ‘0’ ?
I don’t know how to use the analog inputs that’s why I’m asking

Thank you!
 

djsfantasi

Joined Apr 11, 2010
5,704
Yes it has analog inputs
So you mean that doing this is like measuring input voltage and decide in which values my input is ‘1’ and ‘0’ ?
I don’t know how to use the analog inputs that’s why I’m asking

Thank you!
That’s exactly what I had in mind. In the Arduino world, you have to define the pin as an analog input. Then, in the main loop, there is a command to read the voltage on the pin and return a number in the range 0-1023. This number represents the voltage. Then as you have surmised, you determine the numbers that represent a “1” and “0”. I’d use a range, like anything below 100 is a zero; anything above a 500 is a one (numbers like tots made up).
 

Thread Starter

gatoulisss

Joined Jan 23, 2015
55
That’s exactly what I had in mind. In the Arduino world, you have to define the pin as an analog input. Then, in the main loop, there is a command to read the voltage on the pin and return a number in the range 0-1023. This number represents the voltage. Then as you have surmised, you determine the numbers that represent a “1” and “0”. I’d use a range, like anything below 100 is a zero; anything above a 500 is a one (numbers like tots made up).
I’m using mikroc to program the mcu you think this on the picture is what I have to do? 0107EC20-F334-48B8-BC5A-00049D21EBD7.jpeg
 

djsfantasi

Joined Apr 11, 2010
5,704
Yes! Exactly.

The sample program puts the ADC value on PORTB and PORTC. In your case, you’d test the result temp_res against some predefined limits, to determine if the value is a zero or one.

In Arduino, it’d look something like this. I hope you can translate to mikroC.

...
const int zeroMax = 100;
const int oneMax = 500;
...
int temp_res = analogRead(myPin);
if (temp_res < zeroMin) {
my_res = 0;
}
if (temp_res > oneMin) {
my_res = 1;
}
...

In mikroC, you would use ADC_Read() instead of analogRead().
 

Thread Starter

gatoulisss

Joined Jan 23, 2015
55
Yes! Exactly.

The sample program puts the ADC value on PORTB and PORTC. In your case, you’d test the result temp_res against some predefined limits, to determine if the value is a zero or one.

In Arduino, it’d look something like this. I hope you can translate to mikroC.

...
const int zeroMax = 100;
const int oneMax = 500;
...
int temp_res = analogRead(myPin);
if (temp_res < zeroMin) {
my_res = 0;
}
if (temp_res > oneMin) {
my_res = 1;
}
...

In mikroC, you would use ADC_Read() instead of analogRead().

Unfortunately I don’t have any success
I set ANSEL, ADC_INT,
Volt=ADC_READ(1);
Vinp=(Volt*5.0)/(1024);
While (vinp<=100){ do something here }

But nothing it’s like it doesn’t read anything but ‘0’
 

djsfantasi

Joined Apr 11, 2010
5,704
Why are you doing this?

Vinp = (Volt * 5.0) / 1024

That converts the ADC reading to a voltage reading. The possible values are from 0 to 5. Which is ALWAYS < 100.

The numbers 100 & 500 are examples. They are intended to test the raw input, not a scaled input. If you have to scale the input (with the statement I refer to above), then you need to use scaled values for your range.

Describe back to me how you understand the above statements. Then describe what each line in your code does. I can’t explain it to you without a better understanding of what you think n
 

Thread Starter

gatoulisss

Joined Jan 23, 2015
55
Why are you doing this?

Vinp = (Volt * 5.0) / 1024

That converts the ADC reading to a voltage reading. The possible values are from 0 to 5. Which is ALWAYS < 100.

The numbers 100 & 500 are examples. They are intended to test the raw input, not a scaled input. If you have to scale the input (with the statement I refer to above), then you need to use scaled values for your range.

Describe back to me how you understand the above statements. Then describe what each line in your code does. I can’t explain it to you without a better understanding of what you think n
Ok so

ANSEL=0b00000100 // set ra2 as analog
Adc_init() // enable ADC
Volt=ADC_read(2) // take the 10bit reading to volt
Vinp=(volt*5.0)/(1024) // and I was doing this because I thought that this was convert the 10bits to volts
 

djsfantasi

Joined Apr 11, 2010
5,704
It does convert the input to volts, assuming that the variable Vinp is defined as a float.

First, if Vinp is not a float, the result will not be the value of the input volts.

But more importantly, why are you checking if Vinp is less than 100? Don’t you realize that this will ALWAYS be true?
 

Thread Starter

gatoulisss

Joined Jan 23, 2015
55
It does convert the input to volts, assuming that the variable Vinp is defined as a float.

First, if Vinp is not a float, the result will not be the value of the input volts.

But more importantly, why are you checking if Vinp is less than 100? Don’t you realize that this will ALWAYS be true?
Ok so first correction I have to make is the vinp as float
And second the while should be like this : while (vinp<0.1) if I want to have less than 0.1v

Is that correct ?
 

djsfantasi

Joined Apr 11, 2010
5,704
Ok so first correction I have to make is the vinp as float
And second the while should be like this : while (vinp<0.1) if I want to have less than 0.1v

Is that correct ?
That looks much better. I’d also make the divisor in your scaling calculation a float (I.e., 1024.0)
 

Thread Starter

gatoulisss

Joined Jan 23, 2015
55
here it is

C:
unsigned int volt;
float vinp;

void hxos(){                       //hxos 1
sound_play(3400,250);
delay_ms(400);
sound_play(3400,250);
delay_ms(2000);}

void main() {
osccon=0x70;
             
ansel=0b00000100;                  // RA2 analog
adc_init();

trisa=0b00000100;                      //vibr sensor
sound_init(&portb,3);          // buzzer output

for(;;){
volt=adc_read(2);
vinp=(volt*5.0)/(1024.0);
//                  sensor RA2 state
  while (vinp<0.1){
hxos();}                             // sound
}
}
Post the entirety of your code. Note that there is a button with which you can post code.
View attachment 167817
Mod edit: C qualifier in code tag
 
Last edited by a moderator:
Top