Welcome to another blog post about my arduino projects. This week, me and chris decided to investigate tilt sensors. The idea is that coupled with the DHT11 temperature and humidity sensor we can produce a device which can detect the wearer’s level of movement and excursion. We would use the DHT11 to detect the sweat levels of the user and the tilt sensor to detect their movement.
Chris has done a blog post about the general workings of the tilt sensor here.
In order to use the tilt sensor to determine level of movement, I decided that if I could take an average of it’s position over a fixed time period, this could give me a rough idea, the closer the average was to 0.5, the better the level of the users movement. Obviously this is only a very rough estimation and can only really be described as detecting whether or not they passed to either side of an equilibrium point an equal number of times.
The sensor would have to be mounted on its side somewhere on the user’s head, such that it read HIGH when they leaned one way and LOW when they leaned the other.
My first go at writing the code for this was as follows:
This sort of worked, it gave me an average value. However, the FOR statement cycled so fast that the value of the average could only be 0 or 1. This would not do.
Also, viewing through the serial monitor, the value was refreshing so fast that it was impossible to read.
I needed to make sure the sample rate of the tilt sensor was reasonable enough to give me a full range of averages. The idea here was to sample every 10 millisecs, to combat the display problem, I decided to print to serial monitor only every 5 seconds and to reset the average at the same time.
My next go at the code was this:
This was a much closer approximation to what I wanted, here’s what it displayed on the serial monitor:
The values displayed are:
average of the tilt switch
currentmillis (the count value for the sampling)
currentmillis2 (the time value for the display)
the total (at time of printing)
when shaken around violently, I hoped the average would be somewhere around 0.5 but it seemed to jump around from around 0.3 to 0.7 when i was shaking it at a constant rate.
I discovered a number of problems, which could be causing this:
even though I was refreshing the display every 5 seconds, sometimes the total was only sampling 49 times. I thought that this was causing the problem but, when I held the sensor so that there was a constant HIGH value it would still average to 1 or 0.98 which is close enough to be acceptable.
Next I tried holding it to give a constant low value, what I found was that it averaged to around 0.6 and the total (which should be 0) was around 32, which meant it was sampling HIGH over half the time.
Obviously something was up, some noise is clearly being generated causing it to read high 50% of the time.
After re-reading chris’ blog post I realised that I had forgotten to set the internal pull-up resistor. I added a line into the setup code to do just that and the average read as 1 or 0 correctly.
After evaluating the successive averages, I found that it was very difficult to get it close to 0.5 as I needed. I experimented with different sample rates and found that sampling every 500 allowed me to get a reasonable range of averages including 0.5.
With this finished, It was time to build the circuit.
Once I am sure that the circuit and coding works, I will build the circuit on an arduino nano and replace the brightness potentiometer with a resistor.
I then needed to test the circuit before trying to write the code to do what I wanted. I took the earlier code used for displaying ouput from the DHT on an LCD and combined it with the new code I had written for the tilt sensor.
Here’s the code:
Everything worked correctly!
Now I could try to write some code to add more functionality. My goal was to take the inputs from the two sensors and use them to generate a score which would flash up a corresponding message on the LCD screen.
I decided that the easiest way to use the two inputs was to make them comparable and take an average. To begin with the humidity had a range of 0-100 and the tilt sensor average had a range of 0-1 (where 0 and 1 were no movement and 0.5 was max).
First, I needed to adjust the range of the humidity, since although its range is 0 to 100, the actual minimum humidity of a human forehead would be way above 0. I tested this by placing the sensor against my own head, allowing it to stabilize and then taking this as the new minimum value, luckily this ended up being 49, which I rounded to 50, giving me a range of 50 to 100. I subtracted 50 from this to give a range of 0 to 50.
Next I addressed the tilt sensor average by subtracting 0.5, giving it a range of -0.5 to 0.5. Then I took the absolute value, giving a range of 0 to 0.5, with a max of 0.5. I then noticed that I could save myself some work by changing this line:
average = total / 10;
average = total * 10;
This meant that the range for tilt sensor average was now 0 – 50.
With both having the same range I took a mean average and called this the Party Value (PV). I then produced a series of IF ELSE statements for various PV values and corresponding funny messages for the display.
Here’s the code I used: