Thanks for the input simond. This started out as a challenge and has turned into a hobbie. Your points are well taken and I thank you for them. I am in the middle of writing my second sketch right now and I plan on implementing your suggestions. While my sketches are not that complicated, I hope that others will read mem's and your suggestions to me and take a little away from it. After all, helping each other is what the message board is all about.
Thanks to mem and others who helped me through my first project. Here is a link to a video that shows it working in a prototype setup. I am 99% done developing the PCB for this, which will clean it up and shrink it drastically.. Right now it's pretty rude looking but the PCB will make it look nice.
It's a motion activated cell phone that will turn on and keep running as long as there is motion. You can load java2me apps on the phone and they will load upon power up and start running too.
Thanks again to all who have helped. It is up and running great. I used Mem's first revision of my code. The only change I had to make was to declare int FALSE = 0; and int TRUE = 1;. For some reason it wouldn't just take boolean. I never did find another way to check power, so I am going to run some extensive field tests to make sure the possibility of an out-of-sync issue is null. So far, for the past week, I've been ok.
That's a great idea. I see what your saying about being out of sync. I think I'm going to poke around today and look for V when power is on and see what I can find. The phone isnt going to be used by anyone, so it shouldnt be shut off independently of the arduino (it'll be running a Java 2ME program and maybe acting as a server), but I can see if the arduino somehow resets and they'll be out of sync.
BTW..Boarduino arrived yesterday..one step closer to having something I can touch and see working.
#1 This new set of code is going to take several read throughs on my part to understand it. It's not as easy as your other example.
#2 is that the phone can only be wired one way. I had to actually take it apart and solder wires to the metal surfaces of the pushbutton and then run those wires to a 4066 quad bilateral switch which is operated by the i/o pin on the arduino. When you peel the front of the phone away you'll see the the on / off button is actually a metal ring going around a metal dot. The button is a concave round disc that makes contact with the ring and dot when pressed and closes that circuit. Essentially the arduino is like your finger, pushing and holding the on/off button of the phone for 3 seconds. Do it once and that turns the phone on and if you do it again, it turns the phone back off. If you do it quickly, that hangs up a call. If you hold it for 2.5-3 seconds, that operates the power.
This weekend I'm going to load your first suggestion onto my lilypad and give it a test (I'll probably load my first try too, just to see if I could have done it). After that, I have a Boarduino on order and am going to try and get it running at 3.7V (run it at 8Mhz) and then try the code on that because it has a better footprint than the lilypad.
Thank you very much for taking the time to look at the code. You've opened my eyes and I see exactly how your changes cleaned it up. I spent several hours last night coming up with this and I knew that I was overthinking it, but I couldn't quite pare it down myself. Thanks again!!
I've written a sketch (first one) that measures movement with an accelerometer and will turn a phone on and off based on that movement. I'm looking for a constructive critique of the code. Maybe places where it can be cleaned up or made a little more efficient.
Code:
/* -Accelerometer Based Motion Detection System- This system measures motion with a 2-axis accelerometer and if motion is detected within a certain threshold, a digital signal will be sent to switch a phone on or off. Analog values at rest are typically 511. If there is a fluctuation of +or- 3 then it is safe to assume there is movement.
-Code by: SJS Enterprises - -Version 0.01beta- */
int switchPin = 4; //pin that turns phone on and off int xVal = 0; //first x-axis reading in for loop int yVal = 0; //first y-axis reading in for loop int xVal2 = 0; //second x-axis reading in for loop int yVal2 = 0; //second y-axis reading in for loop int x = 4; //analog input pin int y = 5; //analog input pin int xValHigh1 = 0; int yValHigh1 = 0; int xValLow1 = 0; int yValLow1 = 0; int xValHigh; int xValLow; int yValHigh; int yValLow; boolean phoneOn = FALSE;//is phone on boolean movement = FALSE;
//turn on the power to phone when system is initially energized void power(){ digitalWrite(switchPin, HIGH); delay(3000); digitalWrite(switchPin, LOW); xVal = analogRead(x); yVal = analogRead(y); phoneOn = TRUE; delay(3000); }
void setup(){ pinMode(4,OUTPUT); power(); }
void loop(){ //set initial high and low values xValLow = 1023; xValHigh = 0; yValLow = 1023; yValHigh = 0;
/*this 'for' loop grabs accelerometer readings every second for five minutes and stores the highest and lowest values that were received during that time */ for (int i=0; i<300; i++){ xVal = analogRead(x);//first x-axis reading yVal = analogRead(y);//fist y-axis reading delay(1000);//pause for 1 second before taking another axis reading xVal2 = analogRead(x);//second x-axis reading yVal2 = analogRead(y);//second y-axis reading xValLow1 = min(xVal,xVal2);//set minimum value of two analog readings xValHigh1 = max(xVal,xVal2);//set maximum value of two analog readings yValLow1 = min(yVal,yVal2);//set minimum value of two analog readings yValHigh1 = max(yVal,yVal2);//set maximum value of two analog readings xValLow = min(xValLow,xValLow1);//lowest x-axis value during loop xValHigh = max(xValHigh,xValHigh1);//highest x-axis value during loop yValLow = min(yValLow,yValLow1);//lowest y-axis value during loop yValHigh = max(yValHigh,yValHigh1);//highest y-axis value during loop }
//is there movement within threshold on either x or y axis if ((xValHigh-xValLow)>5) || ((yValHigh-yValLow)>5){ movement = TRUE; } else { movement = FALSE; }
//if there is movement and the phone is off then turn it on if (movement == TRUE && phoneOn == FALSE){ digitalWrite(switchPin,HIGH); delay(3000); digitalWrite(switchPin,LOW); phoneOn=TRUE; }
//if there is no movement and phone is on then turn it off if (movement == FALSE && phoneOn == TRUE){ digitalWrite(switchPin,HIGH); delay(3000); digitalWrite(switchPin,LOW); phoneOn=FALSE; }
I want to convert the analog reading from a Wii nunchuck to a range and treat that as a percentage. From what I can tell, the Autoscale will let me do this. It'll take the analog 0-1023 and convert it to -100 to 100, with 0 being the middle. The problem is that I dont understand what the purpose of the inputVariable 'j' is for and how to use it properly.
I want to Serial.print() a float number to a 16X2 LCD. I understand that you cannot Serial.print() a float. I suppose I can multiply my float by 1000 but my decimal point wont show up on the LCD. i.e. 1.500 versus 1500
Any suggestions ???????
Does anyone have any code suggestion to Serial.print(float, DEC) which will print the numbers before the decimal point and then somehow Serial.print(".") and then _somehow_ parse the numbers after the decimal point and print those.
I am by no means an expert, as I am new myself, but I noticed a couple of things that might not be right. I dont know if this is causing a compile error, but it might be something for you to look at.
#1 You are trying to analogWrite on pin 2. analogWrite (aka PWM) only works on Pins 3, 5, 6, 9, 10, and 11. You might want to try digitalWrite(led,HIGH) instead. #2 You are trying to analogWrite the value of 1024 but it only goes from 0-1023. #3 If your number is 381 or higher, it will attempt to print "Type 5" and "Type 4" and "Type 3" and "Type 2" and "Type 1" all at selectLineTwo. 381 is greater than all the other numbers in your If statements and would make them all true. Is this what you wanted? Could this be causing an error? #4 Does Arduino support putting void in the parenthesis after setup and loop such as void loop(void) or void setup(void)? #5 Did you declare the function pressMe() ? Is it void or int or ??? I didn't see that in there.
Maybe I'm way off base but these might be a couple things you could check.
Thanks for the response. What I've decided to do and what will work within the parameters of my project, is to take x and y readings for 5 minutes and catch the lowest and highest values in a variable. If the difference between the low and high is more than 5 (ie.. low=498 and high=504) then I will assume there is movement. Sitting on a device with a vibrating motor and no movement only cased a max diff of 3. Starting and stopping exceeded a value of 5. This way, it doesnt matter what inclination it's on, because it will start with a fresh set of variable values every 5 minutes.
I'm having a problem figuring out how to measure my acceleration using the adxl320. It's a 2 axis accelerometer. I've got it working just fine --assuming that it's starting position is lying flat. The problem is that it's going to be mounted on something different each time and the starting position will not necessarily be horizontal or perpendicular to earth, which means my 1G reading wont be the same (512) each time. I'm looking for some ideas or a kicking off point, on how to measure no movement and then to calculate acceleration, if the device is mounted in a different plane (as compared to earth) each time.
My initial thought is to take readings for 10-15 seconds, when I know i'll be stationary, and average those to get what will be assumed as no motion. Place this in a variable and then start calculating deviations from that point. The problem is, what if the device stops and is on an incline. It will assume that there's movement. I dont know......maybe it's right in front of me and I'm looking harder than I need to.
MikMo -- you're right.....I did mean to round off. Mem -- thanks for the insight. I think I can make your example work. At least it makes sense in my head. I'll have to see if i can put it on paper now.
Well, I know that floating points are difficult to use because they carry out to so many decimal points that comparing two numbers for similarity will almost certainly result in the numbers not being the same. If I can truncate it down to only two decimal places, that will be enough to determine if two results are the same or not. After three or four decimal places, my numbers will start to change, but I dont care about that much detail for my project.
I am converting analog readings (0-1052) to velocity readings which will only change slightly and result in fractions or rather decimals. So, I want to use float, but only carry to two decimal places. I'm just not familiar with C/C++ and it's syntax.