Need help with Memsic 2125
arno
Posts: 43
Helo all,
I try to do a sensor detecto with a Javelin and a memsic 2125, but it's look like it's not working, and I need some help with it.
so here is my code :
import stamp.core.*;
import stamp.util.*;
import stamp.peripheral.*;
import java.lang.*;
public class tracker1 {
final static int xIn = CPU.pin5; // Memsic 2125 input pin X
final static int yIn = CPU.pin6; // Memsic 2125 input pin Y
final static int SampleDelay = 500;
final static int AlarmLevel = 5;
final static int xLimit = 5;
final static int yLimit = 5;
static boolean CarMove = false;
static int xCal;
static int yCal;
static int xMove;
static int yMove;
static int xDiff;
static int yDiff;
static int moTimer;
static void Initialize() {
StringBuffer buf=new StringBuffer(79);
//calibration value for the motion detector
moTimer = 0;
xCal = CPU.pulseIn( 1200, xIn, true);
yCal = CPU.pulseIn( 1200, yIn, true);
xCal = xCal / 10; // some cleanup, for noise and temp
yCal = yCal / 10; // some cleanup, for noise and temp
buf.append( "xCal: " );
buf.append( xCal );
buf.append( ", yCal: " );
buf.append( yCal );
buf.append( "\n\r" );
System.out.println(buf.toString());
}
//
[noparse][[/noparse] Motion Detection ]
static void Motion(){
StringBuffer buf=new StringBuffer(79);
System.out.print("motion loop");
do {
xMove = CPU.pulseIn( 1200, xIn, true);
yMove = CPU.pulseIn( 1200, yIn, true);
xMove = xMove / 10; // some cleanup, for noise and temp
yMove = yMove / 10; // some cleanup, for noise and temp
xDiff = Math.abs ( xMove - xCal);
yDiff = Math.abs ( yMove - yCal);
if ( (xDiff > xLimit) || (yDiff > yLimit) ) {
moTimer = moTimer + 1;
}
if ( moTimer > AlarmLevel ) {
CarMove = true;
}
else {
moTimer = 0;
buf.append( "moTimer: " );
buf.append( moTimer );
buf.append( ", xMove: " );
buf.append( xMove );
buf.append( ", yMove: " );
buf.append( yMove );
buf.append( "\n\r" );
System.out.println(buf.toString());
}
} while (!CarMove);
buf.append( "it has moved !!" );
buf.append( ", xMove: " );
buf.append( xMove );
buf.append( ", yMove: " );
buf.append( yMove );
buf.append( "\n\r" );
System.out.println(buf.toString());
}
public static void main(){
Initialize();
// Wait until the car has moved !
Motion();
}
}
any advice/help will be very valuable,
thanks
arno
I try to do a sensor detecto with a Javelin and a memsic 2125, but it's look like it's not working, and I need some help with it.
so here is my code :
import stamp.core.*;
import stamp.util.*;
import stamp.peripheral.*;
import java.lang.*;
public class tracker1 {
final static int xIn = CPU.pin5; // Memsic 2125 input pin X
final static int yIn = CPU.pin6; // Memsic 2125 input pin Y
final static int SampleDelay = 500;
final static int AlarmLevel = 5;
final static int xLimit = 5;
final static int yLimit = 5;
static boolean CarMove = false;
static int xCal;
static int yCal;
static int xMove;
static int yMove;
static int xDiff;
static int yDiff;
static int moTimer;
static void Initialize() {
StringBuffer buf=new StringBuffer(79);
//calibration value for the motion detector
moTimer = 0;
xCal = CPU.pulseIn( 1200, xIn, true);
yCal = CPU.pulseIn( 1200, yIn, true);
xCal = xCal / 10; // some cleanup, for noise and temp
yCal = yCal / 10; // some cleanup, for noise and temp
buf.append( "xCal: " );
buf.append( xCal );
buf.append( ", yCal: " );
buf.append( yCal );
buf.append( "\n\r" );
System.out.println(buf.toString());
}
//
[noparse][[/noparse] Motion Detection ]
static void Motion(){
StringBuffer buf=new StringBuffer(79);
System.out.print("motion loop");
do {
xMove = CPU.pulseIn( 1200, xIn, true);
yMove = CPU.pulseIn( 1200, yIn, true);
xMove = xMove / 10; // some cleanup, for noise and temp
yMove = yMove / 10; // some cleanup, for noise and temp
xDiff = Math.abs ( xMove - xCal);
yDiff = Math.abs ( yMove - yCal);
if ( (xDiff > xLimit) || (yDiff > yLimit) ) {
moTimer = moTimer + 1;
}
if ( moTimer > AlarmLevel ) {
CarMove = true;
}
else {
moTimer = 0;
buf.append( "moTimer: " );
buf.append( moTimer );
buf.append( ", xMove: " );
buf.append( xMove );
buf.append( ", yMove: " );
buf.append( yMove );
buf.append( "\n\r" );
System.out.println(buf.toString());
}
} while (!CarMove);
buf.append( "it has moved !!" );
buf.append( ", xMove: " );
buf.append( xMove );
buf.append( ", yMove: " );
buf.append( yMove );
buf.append( "\n\r" );
System.out.println(buf.toString());
}
public static void main(){
Initialize();
// Wait until the car has moved !
Motion();
}
}
any advice/help will be very valuable,
thanks
arno
Comments
http://groups.yahoo.com/group/JavelinCode/files/Javelin%20Stamp%20IDE/lib/stamp/peripheral/sensor/accelerometer/
Check that out to see how it is done.
regards peter
·
And I take my code from a Nuts&volts article that was write for the basic stamp, regarding a motion detector.
So that's why I have some problem with my code, I was expecting someone to read my code, not put me a link to some sample.
thanks anyway !
Where in your code do you get unexpected or no results?
That would help to pinpoint any errors.
The other class is supposed to work (I really can't tell if it is
as I don't use a memsic2125) and so how it interfaces to
the memsic2125 is a way to find out if your interface differs
which may be the cause for your class not working.
regards peter
xCal = CPU.pulseIn( 1200, xIn, true);
yCal = CPU.pulseIn( 1200, yIn, true);
xCal = xCal / 10; // some cleanup, for noise and temp
yCal = yCal / 10; // some cleanup, for noise and temp
buf.append( "xCal: " );
buf.append( xCal );
buf.append( ", yCal: " );
buf.append( yCal );
buf.append( "\n\r" );
System.out.println(buf.toString());
I get 56 for xCal and 57 for Ycal, and dosen't matter if I change the position of the board.
for this part:
xMove = CPU.pulseIn( 1200, xIn, true);
yMove = CPU.pulseIn( 1200, yIn, true);
xMove = xMove / 10; // some cleanup, for noise and temp
yMove = yMove / 10; // some cleanup, for noise and temp
xDiff = Math.abs ( xMove - xCal);
yDiff = Math.abs ( yMove - yCal);
if ( (xDiff > xLimit) || (yDiff > yLimit) ) {
moTimer = moTimer + 1;
}
if ( moTimer > AlarmLevel ) {
CarMove = true;
}
else {
moTimer = 0;
buf.append( "moTimer: " );
buf.append( moTimer );
buf.append( ", xMove: " );
buf.append( xMove );
buf.append( ", yMove: " );
buf.append( yMove );
buf.append( "\n\r" );
System.out.println(buf.toString());
I get 0 for both value and I can shack my board as I wan't nothing change !?!?
And that's make me thing something is wrong.
I did the connection like it suppose to be,as explain on the doc of the memsic
I also saw another class where 2000 was used.
It might be your 1200 is too low.
Please try your code with these new timeout values.
regards peter
·
xCal: 57, yCal: 57
moTimer: 0, xMove: 57, yMove: 57, xDiff: 0, yDiff: 0
moTimer: 0, xMove: 57, yMove: 57, xDiff: 0, yDiff: 0
moTimer: 0, xMove: 57, yMove: 57, xDiff: 0, yDiff: 0
moTimer: 0, xMove: 57, yMove: 57, xDiff: 0, yDiff: 0
moTimer: 0, xMove: 57, yMove: 57, xDiff: 0, yDiff: 0
moTimer: 0, xMove: 57, yMove: 57, xDiff: 0, yDiff: 0
and here is the code I did on basic Stamp Working and the value is close to 663 for X and Y
HiPulse CON 1
LoPulse CON 0
SampleDelay CON 500
AlarmLevel CON 5
xLimit CON 2
yLimit CON 2
'
[noparse][[/noparse] Motion detection Variables ]
xCal VAR Word
yCal VAR Word
xMove VAR Word
yMove VAR Word
xDiff VAR Word
yDiff VAR Word
moTimer VAR Word
CarMove VAR Byte
'
[noparse][[/noparse] Main Code ]
Main:
DEBUG "main start"
DEBUG CR
GOSUB Initialize
MainLoop:
GOSUB Motion ' wait for car to move
GOSUB SmsMessage ' send SMS advice car is moving
IF ( CarMove = 0 ) THEN
GOTO MainLoop
ENDIF
END
Initialize:
PULSIN 5, HiPulse, xCal
PULSIN 6, HiPulse, yCal
xCal = xCal / 10 ' some cleanup, for noise and temp
yCal = yCal / 10 ' some cleanup, for noise and temp
Motion:
DEBUG "motion loop"
DO
PULSIN 5, HiPulse, xMove
PULSIN 6, HiPulse, yMove
xMove = xMove / 10 ' some cleanup, for noise and temp
yMove = yMove / 10 ' some cleanup, for noise and temp
PAUSE SampleDelay
xDiff = ABS ( xMove - xCal)
yDiff = ABS ( yMove - yCal)
IF (xDiff > xLimit) OR (yDiff > yLimit) THEN
moTimer = moTimer + 1
ELSE
moTimer = 0
ENDIF
IF ( moTimer > AlarmLevel ) THEN Carmove = 1
LOOP UNTIL (Carmove = 1)
RETURN
I think you are right on it about theis timeout value, it's the only point I'm not sure what it mean. In memsic the pulse suppose to bo something like 10milisec, and for what I understand the timeout is multiple of 8 usec (so arround 1250 sould be fine)
pulseIn
public static int pulseIn(int·timeout, int·portPin, boolean·pinState)Measure the length of a single pulse. Waits for the value of the selected pin to match the value selected by the state parameter and then times how long it takes for the pin to return to its original state. If the pin is an output then it will be changed to be an input and will remain as an input when complete.
A pulse of less than 8.68us in duration may be missed.
Parameters: timeout - the maximum amount of time to spend in the pulseIn method. The timeout covers the complete time of the process—both the wait for the start of the pulse and the time of the pulse. portPin - the I/O pin to measure the pulse on. pinState - whether to measure a high pulse (true) or a low pulse (false). Returns: the length of the pulse in 8.68us units. A value of 0 indicates that no start edge was detected. A value of -1 indicates that no stop edge was detected.
Basic Stamp pulsIn
Function
Measure the width of a pulse on Pin described by State and store the result in Variable.
Quick Facts
Explanation
PULSIN is like a fast stopwatch that is triggered by a change in state (0 or 1) on the specified pin. The entire width of the specified pulse (high or low) is measured, in units shown above and stored in Variable.
Many analog properties (voltage, resistance, capacitance, frequency, duty cycle) can be measured in terms of pulse duration. This makes PULSIN a valuable form of analog-to-digital conversion.
PULSIN will wait for the desired pulse, for up to the maximum pulse width it can measure, shown in the table above. If it sees the desired pulse it measures the time until the end of the pulse and stores the result in Variable. If it never sees the start of the pulse, or the pulse is too long (greater than the Maximum Pulse Width shown above), PULSIN "times out" and store 0 in Variable. This operation keeps your program from locking-up should the desired pulse never occur.
Regardless of the size of Variable, PULSIN internally uses a 16-bit timer. Unless the pulse widths are known to be short enough to fit in an 8-bit result, it is recommended using a word-sized variable. Not doing so may result in strange and misleading results as the BASIC Stamp will only store the lower 8-bits into a byte variable.
If you measure 660 on a BS2 then you should get 660/(8.68/2) = 660/4.34 = 152 on a javelin
This factor 4.34 also relates to your difference calculation. On a bs2sx the factor is 8.68/0.8 = 10.85
(10.85*57 = 618 !! Did you use a bs2sx???)
I think because·the javelin count values are smaller then the BS2 count values
you must adjust your level values. (or do not divide by 10, but by 10/4.34 = 2)
and keep your level values.
Try that.
regards peter
http://forums.parallax.com/forums/default.aspx?f=8&m=87192
As I try to change my code (using the acce
That would explain the value 57 you got.
regards peter
One more question: how did you handle an 'outOfMemoryError ?
After a while my program just crash (a while is a something like 30-45 second)
I know there is some issue about constructo/destructor not handle as it should be (system.out is one of them) but how can I find which function I have to care about this kind of problem ?
thanks in advance
··· // Longest onTime interval is 32,767/50 = 655 * 8.62uS
··· return ( (50 * onTime) / (t2Time / 2) );
The problem there is overflow due to 50*onTime
The formula really equals 100*(onTime/t2Time) where t2Time>onTime
My class UnsignedIntMath has a method ufrac that calculates a fraction for 65536 base
int fr = UnsignedIntMath.ufrac(onTime/t2Time);
It also has a method of multiplying an integer with a 65536 based fraction
return UnsignedIntMath.umulf(100,fr); //return dutycyle in percentage (0-99)
or
return UnsignedIntMath.umulf(10000,fr); //return dutycyle in 0.01 percentage (0-9999)
So the Int32 class can be replaced by the UnsignedIntMath class (which is much smaller)
You can put it all in a single line
return UnsignedIntMath.umulf(100,UnsignedIntMath.ufrac(onTime,y2Time)); //dutycyle in percentage (0-99)
You find the UnsignedIntMath class here
http://groups.yahoo.com/group/JavelinCode/files/Javelin%20Stamp%20IDE/lib/stamp/math/
regards peter
·
toString creates a temporary string and for System.out not required I believe
because System.out.print(buf) also works.
I usually use the Format class which does not use the String at all
and it allows to print values using several bases (bin,octal,dec,hex)
The Format class can be found here:
http://groups.yahoo.com/group/JavelinCode/files/Javelin%20Stamp%20IDE/lib/stamp/util/text/
Another good practice is not to use the keyword 'new' inside methods.
Create global buffers only.
regards peter
So I did globaly and now it's ok
Thanks for your help Peter