I have been working on a project that involves controlling a car with an Arduino board. The car is made of a chassis, two motors, and a battery. The motors are connected to the Arduino board through a motor driver, which allows the Arduino to control the speed and direction of the motors using a wii nunchuck as a remote control.
#include<math.h>#include"Wire.h"#include"WiiChuck.h"#include<Servo.h>#include<RHMotor.h>WiiChuck chuck =WiiChuck();
int joyX =0;
int joyY =0;
#define MOVING_MARGIN 50
#define ROTATE_MARGIN 50
int left_motor_pin =7;
int right_motor_pin =6;
RHMotor motor(left_motor_pin, right_motor_pin);
voidsetup()
{
Serial.begin(9600);
Serial.flush();
Serial.println("Initialize chuck engine.");
chuck.begin(1000);
chuck.update();
delay(1000);
Serial.println("Completed.");
Serial.println("Initialize motor engine.");
motor.start(300);
delay(1000);
motor.stop();
Serial.println("Completed.");
}
voidloop()
{
chuck.update();
joyX = chuck.readJoyX();
joyY = chuck.readJoyY();
//Serial.print(joyX);
//Serial.print(" ");
//Serial.print(joyY);
//Serial.println();
if (millis()%1000==0)
Serial.print(".");
if (chuck.zPress() ==1) {
Serial.println("Z Pressed");
motor.stop();
}
if (joyY > MOVING_MARGIN) {
Serial.println("Fwd");
motor.forward();
} elseif (joyY <0-MOVING_MARGIN) {
Serial.println("Bwd");
motor.backward();
}
if (joyX > ROTATE_MARGIN){
Serial.println("Right");
motor.right(300);
} elseif (joyX <0-ROTATE_MARGIN) {
Serial.println("Left");
motor.left(300);
}
if (chuck.cPress()) {
int left = motor.getLeftServo().readMicroseconds();
int right = motor.getRightServo().readMicroseconds();
Serial.print(left);
Serial.print(" ");
Serial.println(right);
}
joyX =0;
joyY =0;
delay(20);
}
This is a minimalist implementation of roles using a database column to store the roles in plain text. You can specify the role values and a default role that should be used when model is initialized.
Finalmente he hecho una biblioteca I2C_eeprom.
Hay una parte que merece una explicación es el hecho de que estas memorias EEPROM tienen un modo de escritura más rápida (Page Write), en este modo podemos escribir 64bytes de golpe con lo que el proceso de escritura es considerablemente más rápido.
Este modo viene explicado en el datasheet de estas eeproms.
La cosa es que cuando he ido a implementarlo he tenido bastantes problemas.
Lo que he estado programando usa la biblioteca Wire, que a su vez usa unas funciones definidas en Wire\Utility\Twi.h (Two Wire Interface??)
Bien, tanto Wire como Twi usan un buffer interno de 32bytes, y el 24lc256 usa páginas internas de 64bytes, de modo que hay que ajustar estas dos bibliotecas para poder usar el método write_bytes_fast otra cosa importante es que este método no es capaz de saltar de dispositivo, así que estamos limitados a 32k, más que suficiente.
La segunda cosa es que los bloques de 64 bytes deben escribirse completamente, es decir que en cada operación no se pueden escribir ni más ni menos y deben escribirse en su sitio. En 32k hay 512 páginas de 64bytes.
Nota: para usar fast hay que modificar el tamaño del buffer en wire.h y twi.h pero en ambas hay que usar un buffer de 66Bytes, esto es debido a que el direccionamiento
previo son dos Bytes.
#include<Wire.h>voidI2C_eeprom_write_byte( int deviceAddress, unsignedint address, byte data )
{
int rdata = data;
Wire.beginTransmission(deviceAddress);
Wire.send((int)(address >>8)); // MSB
Wire.send((int)(address &0xFF)); // LSB
Wire.send(rdata);
Wire.endTransmission();
delay(10);
}
voidI2C_eeprom_write_page( int deviceAddress, unsignedint addressPage, byte* data, byte length )
{
Wire.beginTransmission(deviceAddress);
Wire.send((int)(addressPage >>8)); // MSB
Wire.send((int)(addressPage &0xFF)); // LSB
byte c;
for ( c =0; c < length; c++)
Wire.send(data[c]);
Wire.endTransmission();
}
byte I2C_eeprom_read_byte( int deviceAddress, unsignedint address )
{
byte rdata =0xFF;
Wire.beginTransmission(deviceAddress);
Wire.send((int)(address >>8)); // MSB
Wire.send((int)(address &0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceAddress,1);
if (Wire.available()) rdata = Wire.receive();
return rdata;
}
voidI2C_eeprom_read_buffer( int deviceAddress, unsignedint address, byte *buffer, int length )
{
Wire.beginTransmission(deviceAddress);
Wire.send((int)(address >>8)); // MSB
Wire.send((int)(address &0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceAddress,length);
int c =0;
for ( c =0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.receive();
}
//*************************************************************************************************
staticvoidDumpHex(int deviceAddress, unsignedlong startAddress, unsignedlong endAddress)
{
int value;
int lineCounter;
char textBuffer[24];
unsignedlong address;
lineCounter =0;
address = startAddress;
while (address < endAddress)
{
sprintf(textBuffer, "0x%05X - ", address);
Serial.print(textBuffer);
sprintf(textBuffer, "0x%05X - ", address + (endAddress - startAddress));
Serial.print(textBuffer);
textBuffer[0] =0;
for (int dumpCounter=0; dumpCounter<16; dumpCounter++)
{
value =I2C_eeprom_read_byte(deviceAddress,address);
Serial.print(value,HEX);
Serial.print(" ");
if ((value >=0x20) && (value <0x7f))
{
textBuffer[dumpCounter %16] = value;
}
else {
textBuffer[dumpCounter %16] ='.';
}
address++;
}
textBuffer[16] =0;
Serial.println(textBuffer);
}
}
voidI2C_eeprom_delete(int deviceAddress, unsignedlong startAddress, unsignedlong endAddress)
{
for(unsignedlong address=startAddress; address < endAddress +1; address++) {
if (I2C_eeprom_read_byte(deviceAddress,address) !=0xFF)
{
Serial.println(address,HEX);
I2C_eeprom_write_byte(deviceAddress,address,0xFF);
}
}
}
#define EEPROM_DEVICE 0x50
#define EEPROM_INIT 0x00000
#define EEPROM_END 0x08000
voidsetup()
{
Wire.begin();
Serial.begin(9600);
long ms;
Serial.println("Deleting..");
ms =millis();
I2C_eeprom_delete(EEPROM_DEVICE,EEPROM_INIT,EEPROM_END);
Serial.print(millis()-ms);
Serial.println("ms");
Serial.println("---- Dump ---");
DumpHex(EEPROM_DEVICE,EEPROM_INIT,EEPROM_INIT+0x0f);
DumpHex(EEPROM_DEVICE,EEPROM_END-0x0f,EEPROM_END);
Serial.println("---- Write at begin ---");
DumpHex(EEPROM_DEVICE,EEPROM_INIT,EEPROM_INIT+0x0f);
Serial.println("Writing...");
I2C_eeprom_write_byte(EEPROM_DEVICE,EEPROM_INIT,0xCC);
I2C_eeprom_write_byte(EEPROM_DEVICE,EEPROM_INIT+0x0f,0xCC);
DumpHex(EEPROM_DEVICE,EEPROM_INIT,EEPROM_INIT+0x0f);
Serial.println("---- Writte at end ---");
DumpHex(EEPROM_DEVICE,EEPROM_END-0x0F,EEPROM_END);
Serial.println("Writing...");
I2C_eeprom_write_byte(EEPROM_DEVICE,EEPROM_END,0xCC);
I2C_eeprom_write_byte(EEPROM_DEVICE,EEPROM_END-0x0f,0xCC);
DumpHex(EEPROM_DEVICE,EEPROM_END-0x0f,EEPROM_END);
Serial.println("---- end ---");
//DumpHex(EEPROM_DEVICE,EEPROM_INIT,EEPROM_INIT+0x0f);
//DumpHex(EEPROM_DEVICE,EEPROM_END-0x0f,EEPROM_END);
}
voidloop()
{
}
He añadido l2C_eeprom_delete para borrar la eeprom, . Tambien he añadido un delay(5) tras cada operación de escritura debido a que si no, no me escribia bien.
Con la biblioteca actual Wire y las funciones I2C_eeprom de (http://www.arduino.cc/playground/Code/I2CEEPROM) .. me he dado cuenta de que las direciones van en un entero (int) que en arduino, son 2 Bytes (16 bits) y con eso no podemos escribir más alla de los 64k, de modo que he cambiaod el código para usar un sistema de páginación.
Por ejemplo con 4 24lc256 tendriamos 4 páginas de 32k lo resumo en estas dos funciones
He tenido muchos problemas y no he conseguido hacer funcionar el ipkg correctamente en la fonera, creo que es un problema de rutas .. al final he hecho una serie de inventos.
cada vez que me ejecuto el “ipkg update” me dan estos errores
ERROR: File not found: //usr/local/lib/ipkg/lists/whiterussian
You probably want to run `ipkg update'
ERROR: File not found: //usr/local/lib/ipkg/lists/non-free
You probably want to run `ipkg update'ERROR: File not found: //usr/local/lib/ipkg/lists/backports
You probably want to run `ipkg update'
en mi ddwrt no hay /usr/local/lib y no puedo crearlo
RedBoot(tm) bootstrap and debug environment [ROMRAM]Non-certified release, version V1.00 - built 10:37:27, Dec 122006Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
Board: FON1
RAM: 0x80000000-0x81000000, [0x80040aa0-0x80fe1000] available
FLASH: 0xa8000000 - 0xa87f0000, 128 blocks of 0x00010000 bytes each.
== Executing boot script in 5.000 seconds - enter ^C to abort
^C
RedBoot> ip_address -l 192.168.1.254/24 -h 192.168.1.5
IP: 192.168.1.254/255.255.255.0, Gateway: 0.0.0.0
Default server: 192.168.1.5
RedBoot> fis init
About to initialize [format] FLASH image system - continue(y/n)? y
*** Initialize FLASH Image System
... Erase from 0xa87e0000-0xa87f0000: .
... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
RedBoot> load -r -b %{FREEMEMLO} openwrt-atheros-vmlinux.lzma
Using default protocol (TFTP)Raw file loaded 0x80040c00-0x80100bff, assumed entry at 0x80040c00
RedBoot> fis create -e 0x80041000 -r 0x80041000 vmlinux
... Erase from 0xa8030000-0xa80f0000: ............
... Program from 0x80040c00-0x80100c00 at 0xa8030000: ............
... Erase from 0xa87e0000-0xa87f0000: .
... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
RedBoot> load -r -b %{FREEMEMLO} openwrt-atheros-root.squashfs
Using default protocol (TFTP)Raw file loaded 0x80040c00-0x801e0bff, assumed entry at 0x80040c00
RedBoot> fis free
0xA80F0000 .. 0xA87E0000
RedBoot> fis create -l 0x6f0000 rootfs
... Erase from 0xa80f0000-0xa87e0000: ..........................................................................
... Program from 0x80040c00-0x801e0c00 at 0xa80f0000: ..........................
... Erase from 0xa87e0000-0xa87f0000: .
... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
RedBoot> fconfig
Run script at boot: true
Boot script:
.. fis load -l linux
.. exec
Enter script, terminate with empty line
>> fis load -l vmlinux
>> exec
>>
Boot script timeout (1000ms resolution): 5Use BOOTP for network configuration: false
Gateway IP address:
Local IP address: 192.168.1.1
Local IP address mask: 255.255.255.0
Default server IP address: 192.168.1.254
Console baud rate: 9600GDB connection port: 9000Force console for special debug messages: false
Network debug at boot time: false
Update RedBoot non-volatile configuration - continue(y/n)? y
... Erase from 0xa87e0000-0xa87f0000: .
... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
RedBoot>