2014_10_27

other robots in "Robots" folder. last one in sub-folder "mouse".

This one called "Moody1" for now.
after much experimentation, kevin got the pick & place set up for the back of the board. 
Looking to program front of board today.


Accelerometer:
MMA8451QR1
DK Part:  MMA8451QR1CT-ND
http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8451Q.pdf
accel MMA8451Q.pdf

Gyroscope:
L3GD20TR
DK Part:  497-12081-1-ND
http://www.st.com/web/en/resource/technical/document/datasheet/DM00036465.pdf
gyro DM00036465.pdf

sold at sparkfun:
L3G4200D
https://www.sparkfun.com/products/10612
http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Gyros/3-Axis/CD00265057.pdf
has the same registers in same positions.
sample code downloaded into "L3G4200D_Example" folder.
"L3G4200D_Example.pde": uses spi but otherwise seems compatible.

L3G4200D.h changed name to L3GD20.h since same registers and copy put into Moody1\Moody1 subfolder.



Wire.h           twi.h
requestFrom() -> uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);

Note: one of the functions in Wire.cpp account for sub-address (register within I2C device)
For writing, just include in beginning of array


They Use same format for read/write single/multiple byte:
accel p.18
gyro p.23-24


Gyro: "In order to read multiple bytes, it is necessary to assert the most significant bit of the subaddressfield."
Accel: "The MMA8451Q automatically increments the received register address commands after a write command is received"


gyro:
p.31
WHO_AM_I	0x0F	
CTRL_REG1	0x20	power up/down, axes on/off, data rate and bandwidth selection (Table 21)
CTRL_REG2	0x21	high pass filter (table 25 and table 26 (use with table 21)) 
CTRL_REG3	0x22	INT1 and INT2 pin
CTRL_REG4	0x23	full scale selection (dps), data msb/lsb, etc.	

FIFO_CTRL_REG (2Eh)


Including header file in arduino:
http://forum.arduino.cc/index.php?topic=37371.0
http://www.arduino.cc/en/Hacking/BuildProcess

Basically, include the .h file in the project, then #include "file.h", and also
add "#include "Arduino.h"" in header file for things like uint8_t, etc.

Tomarrow: can't include sub-files like twi.h so just use Wire.h functions in Moody1I2C
until ready to create custom library. Use code from the downloaded example L3G4200D_Example
along with own functions to create a gyroscope test program.



2014_10_28


void I2CBegin(void)
and made everything in Moody1I2C use Wire.cpp exclusively for now (since can't access twi.c,.h
except from cpp files).

Combined with the example to create gyro test code. compiles.


Sparkfun
MMA8452Q
https://www.sparkfun.com/products/12756
code: https://github.com/sparkfun/MMA8452_Accelerometer/tree/QC-Rev
MMA8452Q Basic Example Code
by
Nathan Seidle

There appears to be "simple" and "advanced". The "library" code contains a "simple" version.
All "simple" and the library use the wire library.
the "advanced" example says it doesn't use the wire library since the part is not 5V tolerant
and the wire library uses an internal 5v pull up (the library and the "simple" example mention
using resistor between arduino and accelerometer power, but seem to ignore the I2C bus
voltage incompatibility).

https://github.com/sparkfun/MMA8452_Accelerometer/tree/master/Firmware/MMA842Q%20Sketches/MMA8452Q_AdvancedExample
MMA8452Q_AdvancedExample
in new sub folder MMA8452_Accelerometer

Moved "Moody1" contents to new folder "L3GD20_Gyroscope".

twi_init() in twi.c has the pull ups activated
Made WireNoPullUp, though not necessary after all since we are at 2.5v instead of 5v (which also means 8mhz instead
of 16mhz)

gyro fifo:
32 slots of 16-bit data FIFO for each of the three output channels.
Put in FIFO mode (old data discarded as new received once full).
Once x/y/z is read in sequence it starts back at x instead of continuing through the registers.
FIFO_CTRL_REG
FM2,1,0: 0 0 1 FIFO mode -> 0x20 | fifo interrupt level (max 0x1F)

Worked out rest of registers needed to put into GyroSetFIFOTriggerLevel() (also sets up for using FIFO in general)
Also created GyroUseFIFOWithoutTrigger() since they (accel and gyro) can't both use the interrupt since they share the same pin.

changed to GyroUseFIFO() and GyroUseFIFOWithTrigger()

accel fifo:

F_MODE > 00 to activate FIFO
OUT_X_MSB, OUT_X_LSB, then continues iwth Y and Z. Unlike gyro, doesn't appear to reset at x when done with z (for multi-register read)
FIFO Status Register for how much fifo is filled, etc.

F_STATUS: FIFO status register


Tomarrow: finish accel FIFO with/without interrupt function, and make gyro (FIFO_SRC_REG) and accel (F_STATUS) FIFOSize functions.


2014_10_29

Finished stuff from yesterday's "tomarrow" including GyroBufferSize() and AccelBufferSize()
AccelGetAxis()

GyroGetAxes() and AccelGetAxes()

GyroZero(), and GyroUpdate() added (and same for Accel).

Motors(), Move(), and Rotate()

Adafruit_NeoPixel-master downloaded

2014_10_30

analogWrite() used to make pwm adjustment for  Motors().
Created MotorsBegin()

Added in #defines for all the pins, with notes.

Added in NeoPixel library.

Maybe borrow serial debug functions from 
C:\Dustin\My Documents\firmware\Source_Code_TI\Robots\Mouse\Mouse_lnk\Lilly2BaseFunctionality01




2014_11_4

Jr2

...(whole week on this)...

2014_11_7

more Jr2 (now got CooCox version of Jr2RxCanon project).

Made PickAndPlace c# project for translating csv spreadsheet numbers into pick & place format.
Finished basic file/folder selection, read, store in integer array, and binary write.




2014_11_10

kevin has been trying for 1.5 days to get bootloader to work on unit.
//
differences: level shift (5v<->3v) and 8 instead of 16mhz. Both of these have been made to
work by other people (though special version for 8 mhz).
//
Chip on programmer board is programmed to be usb-serial converter that also pulls down the reset pin.
He made sure program was correct by extracting firmware from other usb-serial converter(with AVR programmer)
on Uno board then putting it on OUR programming board.
Bootloader is put on robot board with the same AVR programmer
//
He said that programming is started (serial Tx pin) by our programmer board but the robot board never responds.
//
Just tried switching serial rx/tx and making the circuit with the rx/tx identical to arduino.
//





1. Detailed screenshots of Uno and our board attempting to program to see if any noticeable difference. 
2. modify source code of bootloader so just echoes serial and see what happens.
3. Try actually programming their programmer chip and putting on bootloader with avr programmer (16mhz version, in this case) , then
see if the Uno board still programs fine.

Tried all but #2.
Detailed screenshots of uno and our loading process showed that the serial data was almost 10x slower (down from 115200 to about 14400).
Reading of fuses of both chips showed that theirs did not have "div8" set but ours did...
Strange how usb still works...


2014_11_11


arduino in something besides program files so don't have to deal with permissions.
Put newest version of optiboot in it (already has it in a sub-directory but it isn't the latest).

D:\Projects\Moody1Local\arduino-1.0.6\hardware\arduino\bootloaders

Edited optiboot.c in a couple of places (marked with "Dustin") so that it echoes a character
on startup then just echoes any other character it receives.

D:\Projects\Moody1Local\arduino-1.0.6\hardware\arduino\boards.txt
replaced with version in 

moved stuff in
D:\Projects\Moody1Local\arduino-1.0.6\hardware\arduino\bootloaders\optiboot\bootloaders\optiboot
up 2 directories.

cd D:\Projects\Moody1Local\arduino-1.0.6\hardware\arduino\bootloaders\optiboot\
omake atmega328_pro8

Gave errors, though this worked when I called it from original optiboot directory (now renamed optiboot_old)
created hex file optiboot_atmega328_pro_8MHz that starts at 7E00.

Datasheet says that with current fuse settings on board this should be 3F00.
However, the working chips also have boot sections starting at 7E00.

editet ORIGINAL with my lines so I will have a new and old version that I compiled, then:
cd D:\Projects\Moody1Local\arduino-1.0.6\hardware\arduino\bootloaders\optiboot_old
omake atmega328_pro8

Note: sometimes doesn't work the first time...

Then tried "omake atmega328" with original and modified optiboot.c

Serial didn't work so tried just flashing LED (note: this code removed in default version


#define LED_DDR     DDRA
#define LED_PORT    PORTA
#define LED_PIN     PINA
#define LED         PINA4

LED_DDR |= _BV(LED);

Put the blink LED routine in loop with putch(0x55) and works on regular arduino board.
When on OUR board, it runs at half speed, but otherwise all right (though the uart signal
is at odd levels.
He took out a resistor and now the usart is on the right port, at the correct levels, and 
definitely being called (is at address 0x7E00) after boot-up (reset released).
Also: we have a set of fuse bits that works, though we will have to edit the makefile
for the 8mhz version (omake atmega328_pro8) since it has a different start position.
Also: make sure the /8 clock fuse option isn't set.

Kevin just got it to load, though was slow since he set it to use the internal oscillator so was
only going at 38kbaud.

Now, loaded to the second (fully built up) board that still has the resistor on the serial line.




2014_11_12

Jr2: adding Canon PX code.

2014_11_13

connected programmer and windows saw serial port and installed.
Had to change project back to Uno mode.

kevin said I need a new boards.txt file...
Then select "board"  :   ATmega328 Optiboot @ 38,400baud w/ 8MHz Int. RC Osc.
arduinofolder\hardware\arduino 

GyroReadRegister(GYR_WHO_AM_I)
should return 0xD3

not loading
got arduino 1.0.6 (right now running 1.0.5)
works!

Note: unlike sample gyro code, who_am_i register is D4, not D3 (datasheet
matches response)

FIFO gyro code didn't work so just keeping at default and reading x/y/z when
available (first 3 bits of STATUS_REG)
Works!

ACC_P_L_THS_REG in accelerometer has default value of 0x84. Works!

ACC_F_STATUS staying at 0xA0

put on my laptop: got installation version. note: had to r-click to install driver from arduino directory.

r-click to install driver for the unknown USB device (install from arduino drivers folder).
Put neopixel files in arduino library folder.
Compiles and loads!

CharToInt(), StringToInt(), and SerialMenu()

GYR_WHO_AM_I
rg 0f
D4
ACC_P_L_THS_REG
ra 14
84

rg 20
7
wg 20 3
3
rg 20
3

ra 18
0
wa 18 3
3
ra 18
3

But examples I ran at work don't work for gyroscope anymore (values frozen and "new value" flags never set).


going through 
L3G4200D_Example.pde

setupL3G4200D():
wg 20 0f
wg 22 08
wg 23 30

Looks like fourth value in CTRL_REG1 (0x20)
turns off auto power down.

So have to include 
GyroWriteRegister(GYR_CTRL_REG1,0x0F);
before reading gyroscope in even basic mode.
working.

check if correct chip:
ra d
1A

MMA8452Standby() to allow registers to be written to
make sure ra 2a returns a value with bit0=0.
AccelWriteRegister(ACC_CTRL_REG1,AccelReadRegister(ACC_CTRL_REG1)&~1));



wa 2a 0 to set registers
to test readings, first: wa 2a 1
Now, giving readings but they are all over the place (the readings
for the gyroscope at least made sense and changed as I turned
the board).

Problem: was translating the numbers wrong. Fixed.

Just decided to keep it at the "16 bit number with 14 bit
resolution" setting just in case accelerometer upgraded in future.


2014_11_14


SerialMenuWithTests() includes tests from yesterday plus 

gyroscope:

FIFO_MODE in FIFO_CTRL_REG (2Eh).
FIFO_SRC_REG (2Fh)
WTM4:0 in FIFO_CTRL_REG (2Eh).
bypass mode off.
0 1 0 Stream mode

wg 2E 40  //put in stream FIFO mode
Fixed GyroUseFIFO()
rg 2F     //data in FIFO  GYR_FIFO_SRC_REG
20
"empty" flag set
FIFO_EN in CTRL_REG5 (24h)
wg 24 40
now:
rg 2f
DF

so fifo seems to be filling now.
GyroReadRegister(GYR_FIFO_SRC_REG)&0x1F buffer size

now for accelerometer:

0x09: F_SETUP FIFO Setup Register
ra 9
40 as it should be
ra 0
A0  //suggests it has overflowed (and contains 0x20 items).
ra 2a
1  //means that regs not editable but is reading values
Fixed AccelBufferSize() and turned off register editing AFTER setting
to FIFO mode.


ra 2a: reads accelerometer register 0x2a
wg 24 40: writes 0x40 to gyroscope register 0x24
g: periodically prints 3 axes of gyroscope
af: puts accelerometer in fifo mode and prints first 20 values recorded.
gt: periodically prints running totals (for gyroscope this is proportional to total rotation)
x: halts the periodic and running total modes


In GyroUpdate(): 
 GyroPos[j]+=(GyroVel[j]-GyroZeroes[j])/100
to bring down the unnecessary precision.
Appears to be about 1200 counts per 90 degrees.

Increased gyroscope variables to 32 bit so don't have to /100.
Note: with 100ms plus printing, 10-11 in buffer each time it is called.

rg 20
F

so DR and BW bits in CTRL_REG1 are 0.
This gives 95 hz according to p.31

added 'm' function. doesn't seem to move backwards though.

Note: left goes backwards and forwards, but right only seems to go forwards

now, right barely working at all.

also: must increase rate or bouncing from motor over 50 makes gyro inaccurate.


2014_11_17

GyroUseFastFIFO(): upper 4 bits of CTRL_REG1 set to 0xF to bring it up to about 700Hz

today, motors both only go forward, but at least both of them DO go forward.

GyroUseFIFO() put before Rotate() in 't' command.

Reason for weird motor behavior: these doubled up with serial communication.

Note: not enough space in ram for full 100 of RecordedData so only filling to 30.
Note: turning moderately fast by hand (speed & bw bits=0xF):

-24922
-24126
-28544
-32728
-32768
-32768
-32768
-32768
-32768


rg 20
one of (setting data rate & bandwidth)
wg 20 0f
wg 20 ff
wg 20 cf
then
g
not much difference

rg 21 (setting high pass frequency)
0  
note: reg5 (24) shows that high-pass filter is not actually enabled.

Found "sensitivity" in chart on p.9.
FS=250dps: 8.75 mdps/digit
500: 17.5
2000: 70
This is in reg4 (23)
rg 23
0


Note: subtracting ANYTHING from -32768 will wrap unless we first 
change to 32 bit number.
[also changed all acceleration functions to use 32 bit numbers, including this fix]

GyroZero() split up into GyroZeroPosition() and GyroZeroVelocity()

rg 23  (ctrl_reg4)
0

wg 23 10 (change from 250 dps to 500 dps)
wg 23 00 (back to default)
then
gt
hard to turn fast enough to max out values.

GyroSetRangeByte(GR_500dps);
GyroGetRangeByte()
GyroSetFrequencyByte()
GyroGetFrequencyByte()
GyroDegreesToRaw()
GyroRawToDegrees()

GyroDegreesToRaw(number)

GyroUseFastFIFO() no longer necessary after Get/Set Range/Frequency  Byte functions.

after motor turning:

rg 20
FF
rg 22
8
rg 24
40
rg 2e
40


Added code to make it update degrees<->raw function variables
when register 20 or 23(reg1 or reg4) are written to ("rg")

wg 20 0f   (95hz)
wg 23 10   (500dps)
gt

when changed to 190hz, the buffer was about twice as full.
760 hz and 500dps (press "d" afterwards to get data):
90 degrees -> 3907920 
t 90 50
final: 3948294
slowing down from: 8041

t 90 75
final: 4012132
slowing down from: 10459

t 90 100
final: 4350958

slowing down from: 17635
t 90 125

final: 4398955
slowing down from: 18787
t 90 150
final: 4861710
slowing down from: 26998
t 90 175
final: 5021358
slowing down from: 28835
t 90 200

final: 5090903
slowing down from: 31510
t 90 225

final: 5061719
slowing down from: 32720

t 90 255
final: 5517363
slowing down from: 32720

data after subtracting desired endpoint:
8041	40374
10459	104212
17635	443038
18787	491035
26998	953790
28835	1113438
31510	1182983
pretty close to linear: (tab2 in Moody spreadsheet)
51.225x - 422662


2014_11_18


RotationSlide()
Note: this actually takes up more time than expected with the 
32 bit adjustments.

wg 20 8f   (380hz)
wg 23 20   (2000dps)
gt

760 hz is a bit too fast...

http://playground.arduino.cc/Code/PIDLibrary
uses millis()

for now, just getting it set up to run accel & gyro in background.

Gyro:

CTRL_REG3 (22h)
4: PP_OD Push-pull / Open drain. Default value: 0. (0: push- pull; 1: open drain
2: I2_WTM FIFO watermark interrupt on DRDY/INT2. Default value: 0. (0: disable; 1: enable)

FIFO_CTRL_REG (2Eh)
4:0 WTM4-WTM0 FIFO threshold. Watermark level setting

CTRL_REG5 (24h)
6: FIFO_EN FIFO enable. Default value: 0 (0: FIFO disable; 1: FIFO Enable)


wg 22 06  CTRL_REG3 open drain (bit4), watermark interrupt on DRDY/INT2 (bit2)
wg 2e 54  FIFO_CTRL_REG watermark FIFO threshold of 20 and fifo stream mode (bits7:6)
wg 20 0f  CTRL_REG1 all axes on and auto-power off disabled
wg 24 40  CTRL_REG5 fifo enable





Accel:

0x2A: CTRL_REG1
5:3:  0 0 1 400 Hz 2.5 ms

0x2C: CTRL_REG3
0: PP_OD   Push-Pull/Open Drain selection on interrupt pad. Default value: 0.
     0: Push-Pull; 1: Open Drain

0x2D: CTRL_REG4
6: INT_EN_FIFO  Interrupt Enable. Default value: 0.
   0: FIFO interrupt disabled; 1: FIFO interrupt enabled.

0x2E: CTRL_REG5
6: INT_CFG_FIFO INT1/INT2 Configuration. Default value: 0
   0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin
1: IPOL Interrupt polarity ACTIVE high, or ACTIVE low. Default value: 0.
   0: ACTIVE low; 1: ACTIVE high

0x09: F_SETUP FIFO Setup Register
   5:0: F_WMRK5-0
   7:6: 01 for circular buffer


wa 2a 00  CTRL_REG1 inactive but can set registers (bit1)
wa 2c 03  CTRL_REG3 interrupt is OD(bit0), active hgih(bit1), 
wa 2d 40  CTRL_REG4 fifo interrupt enable
wa 2e 40  CTRL_REG5 fifo interrupt on INT1 pin, 
wa 09 14  F_SETUP watermark at 20 measurements
wa 2a 09  CTRL_REG1 400 Hz and active (bit1)
wa 09 54  F_SETUP circular buffer mode (now at 0x54=01010100)

NavigationBegin()
PauseNavigation()
ResumeNavigation()
NavigationPaused()
ZeroNavigationSensors()
GyroFifoOverflow/AccelFifoOverflow

GetGyroPosition(), etc. so interrupt doesn't change half of number
halfway through (since these are 16 and 32 bit numbers but processor is 
only 8 bit.
actually: calling them
GetDirectionRaw(), GetRotationRaw(), GetPositionRaw(), GetVelocityRaw()

fifo:
ra 0
rg


note: not sure if something like gyro H_Lactive in CTRL_REG3 can also be set for fifo out.
If not, then have to make accel 1="fifo has 20" as well.

of course, if no interrupt, then whether in pp or od mode, gyroscope will generall
pull low. same result (on scope) even when all registers in default mode for both chips.

wg 22 30 just to see if it goes up (CTRL_REG3)
it does! (even though the datasheet specifically states that it is for INT1)


tomarrow: find out why constantly high signal is making arduino interrupt 
go in a loop.


2014_11_19


https://www.pjrc.com/teensy/td_libs_TimerOne.html

have it going at 10ms intervals, but not getting to end of handler
so must be taking too long

It looks like the i2c functions are crapping out when called from an interrupt.

http://forum.arduino.cc/index.php?topic=10397.0
post with someone that had same issue. response: i2c DOES use interrupts.

https://www.sparkfun.com/tutorials/326
also: evidently all interrupts are blocking(no interrupt priorities) so, for example, nothing better interrupt
for much more than  a ms or millis() will be off.

accel:
0x0E: XYZ_DATA_CFG Register
FS[1:0]: 1024/2048/4096 counts/g

at 1024 counts/g and 400 hz
g=9.8m/s^2

change in change in velocity=counts * 9800mm/s / 1024counts * dt

counts*9800/1024/400

actually, more like 32768 counts...
//For 2g range and 400hz measurements:
Serial.print(" a= ");Serial.print(-((int32_t)GetAccelerationRaw(1))*(2*9800)/(32768),DEC);
Serial.print(" v= ");Serial.print(-((int32_t)GetVelocityRaw(1))*(2*9800)/(32768)/400,DEC);
Serial.print(" p= ");Serial.println(-(GetPositionRaw(1))*(2*9800)/(32768)/400/400,DEC);


problem: raw position eventually gets past scale of even 32 bit number.

2014_11_20

made some test code for kevin that just moved until 90 degrees.
added code to record stopping point and one second later (and blink
led to show that is ready to be moved).
"d" on serial port prints results.
one motor moving at speed 100:

motor stopped: 94
1 sec later: 122


note: on scope, it looks like the arduino pwm is about 2ms period.

have to do Serial.end() to make it so we can use the motor direction pins again.
have to do pixels.begin(); again after setting pinMode(Light_Bus_BTN1,INPUT_PULLUP);
in order to make the pixels work again.

encapsulated into 
void TestMotorTurn(int TurnDegrees, int left, int right)

Note: NavigationHandler() takes a full 20ms.
just the line with /400 for accelposition takes up 100us.
3x in a row * 13 in buffer = 3900us=almost 4ms.

Note: about 1 full ms for GyroGetAxes()

This time, using 
s 90 255 -255 
d
x
to test motor overshoot (now with 12ms NavigationHandler()), got
y = 0.1029x - 24.27
where x is degrees/sec (raw**2000/(2^15))
and y is degrees overshoot from when motors stopped.



2014_11_21

Navigation.c,.h


gyro:
range	calc dps/dig	"typ" in datasheet	to get to "typ"		
250	0.007629395	0.00875           	1.14687993         
500	0.015258789	0.0175           	1.146880005
2000	0.061035156	0.070            	1.146880005

MiscHardware.c,.h

distance travel function works, but not getting consistent
results from light sensors.


2014_11_24

Made 
Moody1_FullSerialMenuTesting.ino
vs
Moody1_EmptyProject.ino

Note: when 
Output=Proportional+Integral/100;
Motors(Speed+Output,Speed+Output);
->
Output=2*Proportional+Integral/100;
Motors(Speed+Output,Speed+50-Output);
in
MoveStraight() 
in
MiscHardware
so that wiggles when moves, actually ends up going about 10cm more
when set to 60cm (when 60 cm straight, moves exactly 60 cm).

gyro put before accel in NavigationHandlerSimple() in preperation for
possibly doing xy.



void DelayWithNavigation(int ms)


NavigationHandlerSimple
renamed SimpleNavigation()



maybe make pausing & resuming navigation add up to get the 
global (permanent) position variables.

made minimal timing functions using millis():
GetTime(), RestartTimer(), StopTimper().
put in MiscHardware.c,.h


Note:
DelayWithNavigation(50); with alternating between Motors(0,200) and Motors(200,0)
makes it so there is net negative acceleration in the front-placed accelerometer.
So have to do xy to make it accurate with this kind of turning.
See "buggy movement" test.
	DelayWithNavigation(50);
	Motors(0,200);
	DelayWithNavigation(50);
	Motors(200,0);
	dist=GetPositionY()-initdist;
	if((Distance>0 && dist>Distance) || (Distance<0 && dist<Distance))
		break;   

Distance added to MoveStraight() in MiscHardware.c.,h




{cos(angle),sin(angle)}.{ax,ay}
=cos(angle)*ax+sin(angle)*ay

{cos(angle),sin(angle)}.{ax,ay}
=cos(angle)*ax+sin(angle)*ay

for now, doing chirp function (like tone library but really 



C:\Program Files\Arduino\hardware\arduino\cores\arduino
Tone.cpp  (pitches.h)
int tone() function, right before 
switch (_timer)
multiply "ocr" by 2*frequency, divide by whatever frequency
will bring it to desired on-time.

creating new library based on this:
C:\Program Files\Arduino\libraries\Chirp
same but give pwm on-time in us as input.

Created Chirp.h
adding UsOn input to tone()


from circuit diagram:
"Chirp - PB1, can be driven by the MCU's onboard PWM (OC1A) using TMR1"

OCR1A in Tone.cpp code


ref manual:
"If one or both of the COM1A1:0 bits are written to one, the OC1A output
overrides the normal port functionality of the I/O pin it is connected to"

See notes in MiscHardware file.



2014_11_25

ICR1H is not changing value (still at 0).

16 bit registers: High byte must be written first...
and low byte must be read first...

ICR1 is working fine with c taking care of R/W using 16 bit number.
high byte of TCCR1A, however, only seems to be R/W to the low byte.

clue:
"Not all 16-bit accesses uses the temporary register for the high byte. Reading the OCR1A/B 16-
bit registers does not involve using the temporary register."

c 1000 1: 6v
c 1000 5: 9v  (can barely hear at all)
c 1000 10: 12v (can barely hear at few feet away)
20: 15v
30: 16v
40: 16.6v 
50: 17v
60: 17v
200: 17v

gcdgdg
NOTE_G5
NOTE_C6
NOTE_D6
NOTE_G6
NOTE_D6
NOTE_G6


added refernces to remaining light sensors and transmitters.
testing delay between turning on IR light and reading.
for edge sensors/lights, no difference between 1ms and 100ms.

Looks like we need at least 2200us (2500 to be safe) after telling
lights to turn off, before the light NEVER affects the first 
reading taken with the ambient light sensors.

l 2200
...extremely rare, but still occasional bump in readings:
LEdge 7-472 REdge 7-511 LAmb 1015-99 RAmb 48-81
LEdge 0-473 REdge 0-514 LAmb 67-95 RAmb 55-81
LEdge 8-472 REdge 0-513 LAmb 60-93 RAmb 48-77
LEdge 0-472 REdge 0-514 LAmb 63-99 RAmb 48-83
LEdge 0-470 REdge 0-509 LAmb 64-99 RAmb 48-83
LEdge 0-469 REdge 0-498 LAmb 67-108 RAmb 51-81
LEdge 0-469 REdge 1-508 LAmb 67-99 RAmb 51-83



2014_11_26 

100us after switch:
LEdge 292 REdge 207 LEdge 317 REdge 333
LEdge 349 REdge 253 LEdge 260 REdge 361
LEdge 349 REdge 262 LEdge 322 REdge 344
LEdge 345 REdge 252 LEdge 297 REdge 332
LEdge 309 REdge 239 LEdge 267 REdge 339
50us after switch:
LEdge 349 REdge 231 LEdge 104 REdge 342
LEdge 360 REdge 243 LEdge 127 REdge 346
LEdge 364 REdge 250 LEdge 133 REdge 353
LEdge 364 REdge 235 LEdge 142 REdge 361
LEdge 394 REdge 211 LEdge 97 REdge 279


Note: making difference in 50 to 100us after
switching IR_Send on/off implies that it takes quite a while to do the analog read.

//
//Put a bunch of us delays while toggling IR_Send to test delayMicroseconds and how fast IR_Send makes changes.
//
//analogRead() time:
analog read time(from looking at 2 pulses, one with and one without a single
analog read)
572-479=93 us.
93 us for an analog read.
//
//delayMicroseconds() actual time
425us between 400us period pulses(200 on, 200 off)
1260us between when high time increased to 1000 us.
1261-425=836 us per 800 us delay specified
real us=1.045*delayMicroseconds()
//
//Physical rise/fall times:
about 100us longer to get halfway down than it takes to go all the way up.
about 125us to drop all the way.
//
//digitalWrite() time:
2 delays of 200 us in one high pulse, then same but with 4 digital writes up/down.
648 us in regular, 666us with.
18 us total.
//


pull up resistor changed to 2k and now only need 10us delay for ambient light
sensors.

33us seems to be as fast as the tone() function can go when processor is
at 8 mhz. Has to be 26us to transmit at 38k

Just making variation of PlayChirp() called PlayChirpIR().
also has advantage of being able to change pwm  duty cycle so
it becomes an actual square wave.

ModulateIR()

ReadEdgeLightSensors(), ReadLightSensors()

2014_12_1

Have to make navigation loop faster so can stop at full speed.
two parts: I2C and analog read.
wiring_analog.c

Looks like we should use default ref voltage AREF
(default of chip(0b00)...DEFAULT is defined in ARduino.h as 1)

sbi(ADCSRA, ADEN);//enable ADC

ADMUX=(ADC num)&7 
ADCSRA //clock (must prescale down to below 200khz)
sbi(ADCSRA, ADSC);
while (bit_is_set(ADCSRA, ADSC));
low  = ADCL;
high = ADCH;

0b110 prescale:
8000000/64=125000
1/125000*1000*13=0.104 ms per reading.

LookForEdge() in MiscHardware.c,.h
GyroNavigation() in Navigation.c,.h

ExploreBasic() added to MiscHardware.c,.h


2014_12_2

checkFrontSensors() -> CheckSideSensors()
LeftAmbientLightLevel, etc.

'p' command turns serial port into keyboard.



2013_12_3

WireLibraryTest CodeBlocks project made so I can test-compile the code
as I edit it without having to wait for Arduino to give me less useful feedback.
build options->Search directories->
C:\Program Files\Arduino\hardware\arduino\cores\arduino
C:\Program Files\Arduino\hardware\tools\avr\avr\include
C:\Program Files\Arduino\hardware\arduino\variants\standard
build options->Compiler settings->#defines->
__AVR_ATmega328P__
F_CPU 8000000


left side or R11 under front pad.
10us period.
Increased from 100khz to 400khz with:
In twi.h:
#define TWI_FREQ 400000L//100000L

In while loop with just reading gyro:
340us to read gyro axes (117us before next check fifo).
166us to check if any fifo available (72us before next check fifo).
about 2.1ms between axes read (about 10 fifo checks) 

remote communication:
hovers up(when not receiving 38khz signal).
down for 9ms, up for 4.455ms
600-670us down, then 
450-520us up and 600-670us down for 8 times
1580-1620us up, 600-670us down for 8 times
Then, time high (short or long) is binary.

changed serial port tfrom 9600 to 115200 for faster debug.

IR example:
http://playground.arduino.cc/Code/InfraredReceivers
uses same timer as is used for chirp to measure widths
of incoming IR pulses.
Ir library:
http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html
IRremote.zip


2014_12_5

charger broken. using other board to charge extra battery for now.

Note: printing to PC at 115200 fine, but not able to send to chip at this speed.
38400 baud is fine, though.
#define SERIAL_SPEED 38400

PlayChirpIR
got ir-modulations.png from http://irq5.io/2012/07/27/infrared-remote-control-protocols-part-1/

started with sample code
http://playground.arduino.cc/Code/InfraredReceivers
Used this to create InitRxIR() and RunRxIR() and put in 'b' command for menu.
b
Bit stream detected!

9032	0
4424	1
608	0
488	1
624	0
504	1
616	0
512	1

...
584	0
1672	1
616	0
1616	1
616	0
1616	1
608	0
1648	1
584	0
1648	1


matches yesterdays notes on oscilloscope reading.

to MiscHardware.c,.h:
extern char IRNumOfBytes;
extern char IRBytes[20];
extern void RxIRRestart(void);
extern void IRHandler(void);
extern char IsIRDone(void);
extern void IRMenuTest(void);


Suspect that the I2C interrupt is interfering with the IRRx communication.


2014_12_8


begin()
  twi_init()
  TWCR bit0 is TWIE
  removed it from this function

requestFrom()
  twi_readFrom()
  while(TWI_READY != twi_state){
    continue;
  }

TW_STATUS is TWSR register
defined in C:\Program Files\Arduino\hardware\tools\avr\avr\include\util\twi.h

TWI_Handler()
TWCR&_BV(TWINT)


HandleTwiInterrupt()
put it everywhere twi_state appears in while()

need debug (not calling interrupt)

C:\Program Files\Arduino\hardware\arduino\cores\arduino
Print.cpp
HardwareSerial.cpp
UCSR0A

UDR3 = c;




2014_12_11


C:\Program Files\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp
_udr -> UDR0 for this board (looked at HardwareSerial.cpp while inside the
Twi/I2C test project to use "go to definition").
added to modified twi.c:
void PutCh(char c){
  sbi(UCSR0A, TXC0);//=1 to clear transmit complete flalg
  UDR0=c;
  while(!(UCSR0A&(1<<TXC0)));
}

TestCode project: about 2300 bytes with just wire library functions.

IRMenuTest() in MiscHardware


2014_12_19 

Just going to start putting navigation handling in interrupt now so no nasty surprises
later.

WireLibraryTest renamed MoodyWireLibrary

noInterrupts()/cli()
sei() 

millis(), micros(), and delay() all use 8 bit timer0 with its interrupt
C:\Program Files\Arduino\hardware\arduino\cores\arduino\wiring.c:

using 16 bit timer1 to chirp, and send & receive IR pulses.




Note: Timer2 has higher interrupt priority than timer1 which has higher priority
than timer0, so allowing interrupts in Navigation handler still won't let 
millis() update.
see p.65


timer0 overflow flag: TOV0 bit 0 in TIFR0 register

in micros():
#ifdef TIFR0
	if ((TIFR0 & _BV(TOV0)) && (t < 255))

#else
	if ((TIFR & _BV(TOV0)) && (t < 255))
		m++;
#endif

timer0 interrupt vector:
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ISR(TIM0_OVF_vect)
#else
ISR(TIMER0_OVF_vect)
#endif

Either have to at least make some static (local) variables global in Wiring.c
so I can update them in navigation handler, or maybe just keep track of
when the millis() update handler is called (look at overflow bit) and exit
navigation handler at this point. 

Created TimeToUpdateMillis() in Navigation in Moody1 project.

downloaded MsTimer2 library

Added "hardware" section at bottom of this file and updated project notes.

IRReceiving added to MiscHardware.c,.h

Problem: if timer2 times out just before timer0, then the AutoNavigationHandler()
will barely have any time to run at all.
Solutions: either have millis(), etc., use timer2 instead so it can interrupt the
AutoNavigationHandler() on timer0, or add an external interrupt handler routine
to the existing timer0 handler.

Timer0Handler() added to wiring.c (code in 3 places labeled by comment "Moody1").

wiring_analog.c in C:\Program Files\Arduino\hardware\arduino\cores\arduino

AutoNavigationBegin()
ChangeAutoNavigationInterval()




2014_12_22    (note: worked all last week, though sometimes on Jr2)

experimenting using code at bottom of Navigation.h
(NavigationBegin example and AutoNavigationBegin example)

put 
    if(PORTD&(1<<7)){
        PORTD&=~(1<<7);
        PORTD|=(1<<7);
    }
    else{
        PORTD|=(1<<7);
        PORTD&=~(1<<7);
    }
in ISR(TIMER2_OVF_vect) in MsTimer2.cpp

Looks like MsTimer2 library sets it up so it pauses until interrupt handled (using
button).

This behavior is caused by "TCNT2 = MsTimer2::tcnt2;" in ISR(TIMER2_OVF_vect) in MsTimer2.cpp.

removed this and renamed
MoodyMsTimer2

Problem: looks like the routine doesn't actually use the compare function to
reset. Just resets to calculated endpoint on overflow interrupt then counts down.
Result: end up with about 2.02ms period.
Solution: add this functionality in.
Note: in practice, autonavigation still seems to work fine.

When delay of "5":
12-12.5ms to take measurements, on about every other ms.
about 9.5-10ms waiting between measurements.
About 22-23ms total per measurement cycle.
32us from interrupt in MoodyMsTimer2 till beginning of AutoNavigationHandler().
44.6us from interrupt in MoodyMsTimer2 till end of AutoNavigationHandler().
Note: still looks like the 2 are synced up, though timer0 goes twice as fast...

So maybe finish this after IR and about 9.7ms between measurements (about 5 timer intervals).

Note: when spaced "3" apart, 8.8ms on (alternating ms), 5.6ms off, 14.5ms total
5.5, 4.7, and 10.2 if "2" apart.

Note: made CheckSideSensors() loop if _38kHz_Rx low and repeat if low after its done.
this way remote control will be ignored by regular light sensing.
However, blinking ir on/off, even with 720us wide pulses, seems to cause feedback
into the 38k sensor.

Printing "_" when loop and "!" when repeat:

!__!__LEd: 14 REd: 25  0 L: 30 R: 35 B: 8 LAm: 47 RAm: 30 BAm: 60
!__!__!_!_!__!_!_!__!___!__!__!_!__!__!__!_LEd: 18 REd: 25  0 L: 33 R: 33 B: 12 LAm: 40 RAm: 31 BAm: 60
!_LEd: 17 REd: 23  0 L: 33 R: 32 B: 12 LAm: 40 RAm: 32 BAm: 60
!__!__!__!__!__LEd: 21 REd: 26  1 L: 27 R: 40 B: 1 LAm: 49 RAm: 35 BAm: 67
!_LEd: 23 REd: 25  0 L: 40 R: 26 B: 0 LAm: 43 RAm: 39 BAm: 70
LEd: 20 REd: 25  0 L: 23 R: 40 B: 18 LAm: 48 RAm: 32 BAm: 64




2014_12_23

//After IR LED goes on, 38k flickers on/off in erratic fashion (though usually almost always on for a large section) during 
//the first 10-25ms (note: pull down is on for 38k receiver). Doesn't react when IR turned off.

Mostly goes away when nothing to reflect back.

Put code for this test at bottom of MiscHardware.

Made IRReceiving volatile and put into CheckSideSensors() to use instead of checking if 38k IR rx pulled low.

Final form: just wait till not IRReceiving before even calling light measurement
routines and then ignore it till done.

This keeps the sensors reading correctly, but 10-25ms is a long time
after ir obstacle detection to wait until another valid 38khz IR Rx signal...


When IR LED turning off about 850us after turning it on for obstacl detection,
Then IR LED 38k Rx turns on (goes low) about 200us after IR LED turns on, 
then off at about 1.13ms to 1.15ms (after original turn on).

Note: though turning on is what causes the false 38k rx, turning off immediately
does reduce its on time quite a bit (from about 10-25ms with barrier making big
reflection, to only 1.13ms to 1.15ms)

CheckSideSensors() keeps IR LED on for about 708us so it should, if anything, 
keep the 38khz IR Rx filter on for a shorter period of time.

Maybe keep IR receiving routine off for about 1.5ms after IR LED last on.

if(PauseNavigationInterrupt) else
->
if(PauseNavigationInterrupt || IRReceiving) else 
so 
AutoNavigationHandler()
is paused when ir 38khz receiving

Note: have to actually skip CheckSideSensors() (or at least let IR Rx finish
and be handled first) if IR Rx has started.(if(IRReceiving))

Note: also can't run neopixel functions while IRReceiving since they temporarily 
suspend interrupts.

Last issue: make sure IRTransitionCount==0 before RxIrRestart() if have not read 
the bytes yet.


2014_12_30

Looks like new remotes from china use about the same format as the one I
already programmed for (menu 'b').


2015_1_13


2015_1_15

IRMenuTest() no longer exits when serial character recieved (was receiving occasionally when not connected to serial port).



4: 
edge reasonably well, side and ambient working
gyro accurate.
sound working, 
IR working.
LED2 only has green!!!  (all rest working fine)
needs completely full battery to not reset!!!
didn't get to accel test.


3:
edge reasonably well, side and ambient working
gyro accurate.
sound working
IR working.
only LED1 working. 3 and 4 sometimes go on but color random and doesn't generally
change after first time.  

2:
edge perfect, side and ambient working
gyro accurate.
sound working
IR working.
LED3 doesn't turn on. All others working.
Accel seems to be working (using remote to go foreward a few cm).
Motor turning not smooth, though.


2015_1_16

CheckSideSensors() -> ReadSideSensors()

button "1" in the altium remote control (assuming LSB first):
0x00 0xFF 0x09 0xF6

using RunRxIRTest() with #define SAMPLE_SIZE  70
0=low=38khz IR signal present:
#	value	Us	binary digit
1	0	8992	
2	1	4456		
3	0	616
	
4	1	512	0
5	0	584	
6	1	544	0
7	0	592	
8	1	512	0
9	0	624	
10	1	512	0
11	0	576	
12	1	544	0
13	0	592	
14	1	512	0
15	0	624	
16	1	512	0
17	0	584	
18	1	536	0		
19	0	592
				8976
20	1	1648	1
21	0	584	
22	1	1648	1
23	0	616	
24	1	1640	1
25	0	592	
26	1	1640	1
27	0	584	
28	1	1656	1
29	0	608	
30	1	1648	1
31	0	584	
32	1	1640	1
33	0	584	
34	1	1648	1
35	0	592	
				17912
36	1	1672	1
37	0	592	
38	1	512	0
39	0	592	
40	1	536	0
41	0	584	
42	1	1648	1
43	0	584	
44	1	544	0
45	0	608	
46	1	520	0
47	0	592	
48	1	512	0
49	0	584	
50	1	544	0	
51	0	592
	
52	1	544	0
53	0	592	
54	1	1632	1
55	0	584	
56	1	1648	1
57	0	592	
58	1	544	0
59	0	584	
60	1	1640	1
61	0	624	
62	1	1640	1
63	0	592	
64	1	1648	1
65	0	584	
66	1	1640	1
67	0	616	

68	1	39728	


void TxIR(char *Data, int Length) added to MiscHardware

menu command "c" now contains TxIR() instead of just raw signal hardware test.

case 'm' in menu:
pos=2;       
        i=0;
        while(1){
          Size=StringToInt(serdat+pos,&(datar[i]),10);
          if(Size==0)
            break;
          pos+=Size;
          i++;
        }
        if(i==4){
          MoveStraightWithOptions(GetDegrees(), 150, 600, 3000, 300, BackAwayFunction, 
                                    datar[0], ((float)(datar[1]))/1000, ((float)(datar[2]))/1000, ((float)(datar[3]))/1000);
        }


m 200 1000 10 500

m 200 1000 10 0

realized that we probably can't see the derivative term at this speed (since not adjusting per second)
and that integral is multiplied to become really large.
Might need to have option "1/10 of a degree" to use derivative term.
Or just use GetDegreesPerSecond()

this works pretty well:
m 100 1000 5 0

change name to MoveStraightWithFullOptions() and made new
MoveStraightWithOptions() that just has edge function and "int Wiggle".
works. 


Making MaintainPosition() demo program in MiscHardware.

GetAcceleration() and GetVelocity()
->
GetAccelerationY() and GetVelocityY()


things that would make MaintainPosition() easier:
function to determine if still (built into navigation)
ability to auto re-zero of velocity (if determined to be still)
add Y accel proportional to abs(DegreesPerSecond())

(then change other movement functions to work with new navigation(if necessary))



2015_1_20

creating Moody1New

ResumeNavigation() now clears buffers and updates instantaneous values as well.

added reading of current values of non-calculated axes of gyro & accel to SimpleNavigation() and SimpleGyroNavigation()

GetAccelerationX() and GetAccelerationZ()
In addition to GetDegreesPerSecond(), have GetDegreesPerSecondX() and GetDegreesPerSecondY()


data[3] in SimpleGyroNavigation(), SimplyNavigation(), etc. is optimized out of existence by compiler unless made global (since is set by pointer
instead of explicitly).
didn't notice before since was previously using it pretty soon after data stored to it so values weren't overwritten.

changed from data to nav_data

Making GyroRawToDegreesPerSecMult and GyroDegreesPerSecToRawMult opposite sign to prev since x & y are fine without "-" and z sign is 
already fine when working with Radians (just not degrees).

GyroRawToSkidMult also changed as a result, so double check.

SetPixelRGB() changed so 1-6 instead of 0-5, and all instances used in MiscHardware sketch changed as well.

finished up to example where user can enter in heading and it turns to that heading when buttons pressed.


2015_1_21

MoveStraightWithOptions() -> MoveWithOptions()

temporarily adding blinking LEDs to move and simple rotate functions (for the purposes of video recording).

void ReadEdgeLightSensors(char Averages) (now has an input)

examples labeled first through eighth shot in Moody1New created (and all but the last one recorded).


2015_1_22

RotateAccurate() in MiscHardware

Note: using GetAccelerationX() and GetAccelerationY() with SimpleNavigation() doesn't work for bump detection since
these just give the last values in the buffer, which aren't always the same as the values when it was bumped.

Works, except that when bump is too brief, it measures slide acceleration direction instead, which is generally 180 degrees
opposite to bump direction.

waiting 100ms before measuring skid and changing direction if this is the same as initial bump.

However, if vibrating as skidding then sometimes still gets it wrong by 180 degrees.

reactions: attack, turn yellow and run away, move away first 2 times,then attack.


2015_1_26


ExploreBasic() -> ExploreExample()

MaintainPosition() -> MaintainPositionExample()

created
C:\Dustin\My Documents\firmware\Source_Code_TI\MoodyExamplesBeta
out of commented out examples in Moody1New


IsIRDone() modified so must be more than one IRTransitionCount (which might be caused by a single short IR blink)
before it returns 1.
ExploreExample() clears IR buffer at beginning (waits 200ms then calls RxIRStop()).
fixed "circular loop" and "stuck in a corner" direction handlers (setting of BAckAway).
RxIRRestart(); after playing any sound.
signed char dir;

Problem: if !IRReceiving, then Navigation functions pause.
The IR receiving does seem to be triggered occasionally so this is probably the issue.

to verify that navigation is paused:
when button pressed, now prints direction, dps, and heading.
these are constant when bug.

In order to track down cause:
if(!PauseNavigationInterrupt && !IRReceiving){
got rid of each separately and it was !IRReceiving that definitely caused problems:

pressing button: noticed that IRTransitionCount stayed at 1 with bug.

IsIRDone(): back to only requiring IRTransitionCount>=1 or navigation handler never resets "IRReceiving"

ExploreExample(): bring back "if(IRNumOfBytes==4)" from a long time ago.


2015_1_27

starting with Moody_Behavior020_ExploreExampleFixed (made from code I fixed last night)

While working on behavior 24, fine tuned MoveWithOptions() so both straight & buggy modes work better, debugged
a bit, changed integral term, and added a fully functional derivative term (as long as bugginess set to 0 or
it keeps it from wiggling more than a tiny amount).


tomorrow: behavior 026: goes crazy even when TxIR() taken out of ExploreExample() so something else must be wrong...


2015_1_28

problem with 026: ended up deleting line to stop motors after turning.

in RotateAccurate() (for recleiving robot of this shot), made it stop motors if timeout

changed MoveWithOptions() so that it looks at direction before starting motors.
(changed these to make behavior011 to a better square)

still a bit of drift on first movement, so just setting initial heading to -5 degrees.

Finished up through behavior 029 (needed to look at current running average and compare to running average when initialized
to detect intruder outside cave)

next complicated behavior: short drives in various directions, using trig to keep track of position so it stays within
a set square.

Just modify normal "move straight" so that it turns on headlights when motors off, then turns around (by a random amount) and
calculates how far to edge in that direction.
Should show edges of a box in red in time lapse.

For this one, making ZeroNavigationSensors() also zero AccelVelocity[]
also: int32_t initdist;//so don't overflow after too many calls in MoveWithOptions()

2015_1_29

fixed x & z acceleration for SimpleNavigation() for behavior008 (wasn't checking if new acceleration values before subtracting
zero values from these axes)


already:  FS[1:0] set to 00   2g Mode
is at 400hz mode. options or 100,200,400, and 800 hz.

finished virtual box example.
Created NavigationXY() from SimpleNavigation()


2015_1_30

AccelData tab in Moody1.xlsm

IRMenuTest() now using updated movement functions for behavior 035
IRrRemoteControl


using behavior 030 for example code to put on video


still working on 
Moody_Behavior034Beta_RecordingAccelAndGyro
though have completed behavior 035


2015_2_2

starting behavior 036, XY accelerometer and gyroscope.

in MoodyWireLibrary, twi.h TWI_BUFFER_LENGTH decreased from 32 to 16
in MoodyWire.h: BUFFER_LENGTH decreased from 32 to 16

behavior 036 data on tab AccelXYGData in Moody1 spreadsheet.


100hz accel data:
did behavior 033 with
AccelWriteRegister(ACC_CTRL_REG1,0x0);// 0x2a inactive but can set registers (bit1)  
  AccelWriteRegister(ACC_CTRL_REG1,0x19);// 0x2a=0x19 is 100 Hz and active (bit1)
added after NavigationBegin()
Put data in Accel100Hz tab.

Noise level not really improved (actually worse or this particular data)

GyroRawToDegreesPerSecMult=((float)GyroRange)*0.0000355;// 1/2^15=1/32768=0.000030517578125      // 1/2^15*1.14688=exactly .000035
GyroRawToDegreesMult=GyroRawToDegreesPerSecMult/GyroFrequency;

Got version (calculating x/y/theta) that works like spreadsheet formula.
Now, working on "INT_VER"


2015_2_3

got under 1/3ms
Moody_Behavior037Beta_RecordXYAccelAndGyroWithIntegerCalc
making version to put in NavigationXY() in Navigation file.
GetAccelerationX(), etc. all have to be changed.
AccelDistance (total y in travel path)
XYMode added to tell GetAccelerationX(), etc. which navigation function was called: SimpleNavigation() or NavigationXY().

tested NavigationXY() where each value its algorithm printed out. these values were put in excel and final XY matched.


2015_2_4
added parameter Sensitivity to NavigationXY()

new inputs added:
NavigationXY(int GyroSensitivity, int AccelSensitivity)

determine if stopped and don't drift.

IsStationary

int GyroAccelerationZ=0,GyroVelocityZPrev=0;

Moody_Behavior038Beta_IRRecordRawTimings with RunRxIRTest() from Moody1 project.
Moody_Behavior039Beta_NavigqationXYTestFunction
Moody_Behavior040Beta_LightSensorRawRecording
Moody_Behavior041Beta_NavigationXYBuggyMovementTest.ino


2015_2_5

NavigationOutOfRange

LookForEdge() updated to also look for white tape

Now, ResumeNavigation() also resets accelerometer velocity.


Note: for NaigationXY(), can't just continuously adjust to XY since direction of endpoint will change over time.

Discovered: possibly less accurate when no wiggles since when wiggles, it bounces forward and backward instead of potentially
just leaning back or forward.

starting to suspect it is actually the fact that zeroing out tilt only works if 
you keep pointing the same direction on the surface.

NonStationaryValue

RotateAccurate() now uses navigationXY

2015_2_6:

note: re-zeroed sensors before moving and it worked much better.

possible big reason for why it will go several times dead on, then be erratic: heights of motors.

if +/- 1 degree (at least this much on average): 
Sin(2 degrees)*9800mm/s^2=0.034899496702500971645995181625333*9800=342.01506768450952213075277992826mm/s^2
so if if tipped all the way one way for zeroing, and all the way the other when traveling, then it will
be 34cm off after one second.



offsetx1,offsety1,etc. for the return to initial position example.

stuff needed for WaitForIRButton() generated by 
"IR" tab in "Moody" spreadsheet.

2015_2_24

put 2015_2_6 MoodyAll backup into "Ringo" folder in laptop



2015_2_26

Moody1New changed to Ringo in arduino project.


created BrightnessNavigationExample

Created behavior 046: simple edge detection
left sensor going off edge:
Left	Right
519	373
529	376
518	373
513	366
486	359
471	357
455	349
427	341
Averages:
489	361


Ringo_Behavior046Beta_SimpleEdgeFunctionAndRecording

backed up...

added to Navigation:
int MinTurn(int ChangeInDegrees)
int VectorToDegrees(int x,int y)

Concatenate range function for openoffice:
[Issue] Concatenating Arrays (View topic) • Apache OpenOffice Community Forum.html
needed it since Ringo.xlsm -> Ringo.ods
 Tools>Options>Security>Macro Security
Changed name from VVJOIN() to ConcatRange()

sheet10 tab raw data compared to Misc tab (current data): looks like less noise in this
robot, possibly because of LIPO battery.

2015_2_27

note: oscillation in raw data still shows up. but have to only take reading from one sensor
to be fast enough to see it.

C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino
wiring_analog.c
__AVR_ATmega328P__ defined according to 
http://electronics4dogs.blogspot.com/2011/01/arduino-predefined-constants.html

analogPinToChannel() in pins_arduino.h is only for __AVR_ATmega32U4__
ADMUX = (analog_reference << 6) | (pin & 0x07);
// start the conversion
	sbi(ADCSRA, ADSC);

	// ADSC is cleared when the conversion finishes
	while (bit_is_set(ADCSRA, ADSC));

Made FastReadingLeft(), etc., but not significantly faster.


micros()  (8us resolution in 8mhz board, resets after about 70 minutes)

about 1.3ms per high frequency oscillation, and the 16.6666/2 ms (60 hz * 2) oscillation from lights.
right now, taking about 4 readings per ms.
5 readings/1.1ms when GetTime() taken out.
slight delays should give 6 readings per about 1.3ms oscillation period.

also: seeing higher order oscillation now that is every other reading.

called it behavior 047






todo: 
*Finish:
  changed NavigationXY() motion detection from comparing absolute value of zeroed reading to difference between one and the next
  (since it might be tipped since last zeroing).
  also made it necessary to move twice before considered moving

* Edge detection should look at increases in addition to decreases so white tape can be used on dark table.
* on tilted surface, accelerometer zeroes would have to adjust with orientation.
* figure out why offset in navigation of few degrees first time MoveWithOptions() called (2015_1_28)
* if TxIR() called after RxIRRestart(), IRReceiving=1 and never turned off
* stop chirp if IR Rx starts (and maybe continue after it is done)
* use IR timer with interrupt for IR Rx timeout.
* pixels don't refresh unless changes have been made to at least one pixel
* function to determine if not moving (built into navigation)
* ability to auto re-zero of velocity (if determined to be still)
* easy: add Y accel proportional to abs(DegreesPerSecond())
* put analog readings into an analog interrupt handler. double buffer (move to 
regular analog readings variables when function called from main loop)
* fix MoodyMsTimer2 so it uses output compare register so stays in sync with timer0 (from 2014_12_22)
* wait the 100us for analog reading while I2C is sending/receiving bytes.
* put PixelsToButton/ButtonToPixels inside button & pixel functions.
* maybe put checking & turning off certain LEDs inside functions such
  as CheckSideSensors()
* switch back to IR receiving after playing tone (if on to begin with)
* Put some of MiscHardware into something like MoodyFunctions so Navigation references
  MiscHardware but not the other way around.




asdf






Moody1           	Main code
L3GD20_Gyroscope	gyroscope test
MMA8452_Accelerometer	accelerometer test
WebDocs

L3G4200D_Example	some code from this used in gyroscope test "L3GD20_Gyroscope"
AnalogReadSerial	sample project
WireNoPullUp      	not needed since we are running at 3.5v (so liminted to 8 mhz) anyway. Note: max voltage is 3.6.


C:\Program Files\Arduino\libraries
C:\Program Files\Arduino\hardware\arduino\cores\arduino




Moody1 arduino project:

Need to replace boards.txt file in folder arduinofolder\hardware\arduino  with new version.
Then select "board"  :   ATmega328 Optiboot @ 38,400baud w/ 8MHz Int. RC Osc.
select correct serial port
select programmer->arduino as ISP

also: add in newpixel folder to libraries.
have to do Serial.end() to make it so we can use the motor direction pins again.
have to do pixels.begin(); again after setting pinMode(Light_Bus_BTN1,INPUT_PULLUP);
in order to make the pixels work again.

MoodyWireLibrary:
wiring.c: in C:\Program Files\Arduino\hardware\arduino\cores\arduino
Timer0Handler() added (code in 3 places labeled by comment "Moody1").
Then completely changed around so that doesn't make use of interrupt so
that it can be PUT into an interrupt


I2C #defines:
C:\Program Files\Arduino\hardware\tools\avr\avr\include\util\twi.h

MoodyMsTimer2
http://playground.arduino.cc/Main/MsTimer2
put into C:\Program Files\Arduino\libraries
Changed so timer not reset on interrupt (so always stays synced with timer0)
Note: another options is to use Timer0Handler to wiring.c instead




//MoodyWiring:
//For now, using timer2 for navigation interrupt instead of editing timer0 handler so no core functions have to be edited.

//
//In twi.h:
//#define TWI_FREQ 400000L//100000L
Note: now just have own "MoodyWire" version of file since changed so doesn't need
to use interrupts.
//
//Tone library is here:
//C:\Program Files\Arduino\hardware\arduino\cores\arduino
Note: now just using own tone function since also need pwm (in addition to frequency)
//
//Ir library:
//http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html
//IRremote.zip
Note: Just using own custom library so don't have to include all their massive list of functions.
//





https://www.pjrc.com/teensy/td_libs_TimerOne.html



MoodyWire:

MoodyWireLibrary CodeBlocks project:  (to create "MoodyWire" arduino library)

//
build options->Search directories->
C:\Program Files\Arduino\hardware\arduino\cores\arduino
C:\Program Files\Arduino\hardware\tools\avr\avr\include
C:\Program Files\Arduino\hardware\arduino\variants\standard
C:\Dustin\My Documents\firmware\Source_Code_TI\Moody1\MoodyWireLibrary\MoodyWire\utility

build options->Compiler settings->#defines->
__AVR_ATmega328P__
F_CPU 8000000

C:\Program Files\Arduino\hardware\arduino\cores\arduino\Print.cpp,.h included
for debug.
//
use this project (MoodyWire) instead of 
C:\Program Files\Arduino\libraries\Wire


Hardware:

timer0:  millis(), micros(), and delay()
timer1: Chirp, IR send, IR receive.
timer2: AutoNavigation timer.

interrupt 1 (I/O 3 which is _38kHz_Rx)




useful stuff:

noInterrupts()/cli()
sei() 


uint8_t oldSREG = SREG;
cli();
//code
SREG = oldSREG;




