>What is EEPROM / E2PROM ?

>

We do need a way to save the numbers which represents the current situation of the robot actuators somewhere(either at PC or somewhere on Arduino microcontroller, EEPROM here). This post dedicates itself to storing data on Arduino non-volatile memory and use this information for zero positioning of the moving joint. First an introduction to EEPROM from Wikipedia and later code example and links to its API’s at Arduino website.

What is EEPROM ?
EEPROM (also written E2PROM and pronounced “e-e-prom,” “double-e prom” or simply “e-squared”) stands for Electrically Erasable Programmable Read-Only Memory and is a type ofnon-volatile memory used in computers and other electronic devices to store small amounts of data that must be saved when power is removed, e.g., calibration tables or device configuration.

When larger amounts of static data are to be stored (such as in USB flash drives) a specific type of EEPROM such as flash memory is more economical than traditional EEPROM devices. EEPROMs are realized as arrays of floating-gate transistors.
EEPROM is user-modifiable read-only memory (ROM) that can be erased and reprogrammed (written to) repeatedly through the application of higher than normal electrical voltage generated externally or internally in the case of modern EEPROMs. EPROM usually must be removed from the device for erasing and programming, whereas EEPROMs can be programmed and erased in circuit. Originally, EEPROMs were limited to single byte operations which made them slower, but modern EEPROMs allow multi-byte page operations. It also has a limited life – that is, the number of times it could be reprogrammed was limited to tens or hundreds of thousands of times. That limitation has been extended to a million write operations in modern EEPROMs. In an EEPROM that is frequently reprogrammed while the computer is in use, the life of the EEPROM can be an important design consideration. It is for this reason that EEPROMs were used for configuration information, rather than random access memory.*
Practical Information about how to get things to work : 

Source Code : 


#include EEPROM.h

int a = 0;
int value;

void setup()
{
Serial.begin(9600);
for (int i = 0; i < 20; i++){
Serial.println("***");
EEPROM.write(i, i);
}
}

void loop()
{
value = EEPROM.read(a);

Serial.print(a);
Serial.print("t");
Serial.print(value);
Serial.println("***");
a++;

if (a == 20){
a = 0;
Serial.println("DONE");
delay(5000000);
}
}

* : Source : Wikipedia

>Problem of current position in case of loosing power & possible fixes …

>I think I have found my way to bear in mind the current position of the robot in case of the robot loosing power & not being able to drive itself back to the ZERO. The way is to either use the built in EEPROM(512 bytes), or other external storages which can be connected to Arduino. More info about EEPROM :

The 2nd option is to always send the position to the computer and save it somewhere there at the program(Lots of traffic on serial port, higher risk to encounter problem or missing packages).

Too tiered to fix it now … Later …

>It matters to choose BYTE or INTEGER, BUG fixed + Handshaked protocol added

>Just now fixed a bug in my code. Choosing BYTE as my variable type made some confusions on startup for the program as it couldn’t initialize the variable with 0 value. The problem was fixed as soon as I changed the type to INTEGER. This resulted in errors in my program as no value made some random cases to launch which was totally wrong. This means that the bug on startup of my program which I talked to my supervisor today about is fixed :-) I was thinking as it just happened on startup to be a noise or some wrong reading from ports on Arduino, but it seems to be just a confusion on defining the variable as byte !!! I have also changed the startup value from 0 to -1 which result in no possible meaningful combination …

Differences with previous code : Handshake added, Startup bug fixed, Some changes in standard writing to serial port from Arduino side.



//the code is entering saving with Java and we are printing as little as possible in Serial ports
// Encoders inputs
byte pinEncA[] = {7,5,3}; // digital inputs
byte pinEncB[] = {6,4,2}; // digital inputs

// MOTOR OUTPUTS
byte pinDir[] = {13,8,12}; // digital output, controls direction for motor nr. [x]
byte pinPwm[] = {10,11,9}; // analog output, controls motor speed, nr. [x]

//Global variables
int readValue;
int pwmValue;
int motorDir;
//int channelA = 2;
//int channelB = 3;
int cycle[] = {0, 0, 0};

boolean f = false, b = false, r = false, l = false;
int cyclecounter[] = {0, 0, 0};
int cyclecounterold[] = {0, 0, 0};

//13 , 10 right, down
//8 , 11 middle, top
//9, 12 left, down



void setup(){

Serial.begin(115200);
Serial.println("WELCOME TO C1S0");
for (int i=0; i < 3; i++){
pinMode(pinDir[i], OUTPUT);
pinMode(pinPwm[i], OUTPUT);
//in case, just to be sure ...
digitalWrite(pinPwm[i], LOW);
// just in case to be sure
digitalWrite(pinDir[i], LOW);
pinMode(pinEncA[i], INPUT);
pinMode(pinEncB[i], INPUT);
digitalWrite(pinEncA[i], LOW);
digitalWrite(pinEncB[i], LOW);
cyclecounter[i] = -1;
cyclecounterold[i] = -1;
}//end of for

}//end of setup()

void loop(){
commandCenter();
checkEncoder();
}//end of loop

void commandCenter(){
//variables
int temp = 0;
if ( Serial.available() > 0 ){
readValue = Serial.read();
switch (readValue){
case 'h' : //handshake
Serial.println("h");
break;
case '0' ://motor #0
int temp__;
temp__ = 0;
if(Serial.available() < 0)
;
delay(500);
temp__ = Serial.read();
if (temp__ == 102){// -f -> forward
Serial.println("*** Right forward ***");
digitalWrite(pinDir[0], LOW);
digitalWrite(pinPwm[0], HIGH);
}//end of if
else if(temp__ == 98){// -b -> backward
Serial.println("*** Right backward ***");
digitalWrite(pinDir[0], HIGH);
digitalWrite(pinPwm[0], HIGH);
}
else{

Serial.print("error ");
Serial.println(temp__);
}
f = false;
b = false;
l = false;
r = true;
break;
case '1' ://motor #1
int temp_;
if(Serial.available() < 1)
;
delay(500);
temp_ = Serial.read();
if (temp_ == 102){// -f
Serial.println("*1FW*");
digitalWrite(pinDir[1], LOW);
digitalWrite(pinPwm[1], HIGH);
}//end of if
else if(temp_ == 98){// -b
Serial.println("*1BW*");
digitalWrite(pinDir[1], HIGH);
digitalWrite(pinPwm[1], HIGH);
}
else{

Serial.print("error ");
Serial.println(temp_);
}
f = true;
b = false;
l = false;
r = false;
break;
case '2' ://l -> left
temp_ = 0;
if(Serial.available() < 1)
;
delay(500);
temp_ = Serial.read();
if (temp_ == 102){//motor #2
Serial.println("*2FW*");
digitalWrite(pinDir[2], LOW);
digitalWrite(pinPwm[2], HIGH);
}//end of if
else if(temp_ == 98){// -b
Serial.println("*2BW*");
digitalWrite(pinDir[2], HIGH);
digitalWrite(pinPwm[2], HIGH);
}
else{

Serial.print("error ");
Serial.println(temp_);
}
f = false;
b = false;
l = true;
r = false;
break;
case 82 : //R->RESET
Serial.println("*** Resetting ***");
for (int i=0; i < 3; i++){
digitalWrite(pinPwm[i], LOW);//Setting all PWM's to LOW
Serial.print("C");
Serial.print(i);
Serial.print("=");
Serial.println(cycle[i]);
}//end of for
f = false;
b = false;
l = false;
r = false;
break;
}//end of switch
}
/*
if (f || b || r || l){
Serial.print("cycle[i]: ");
Serial.println(cycle[i]);
}//end of if
*/
}//end of commandCenter

//int angleMaalt;

void checkEncoder(){
int A;
int B;
int i;
for (i = 0; i < 3; i++){
A = digitalRead(pinEncA[i]);
B = digitalRead(pinEncB[i]);

if ( (A==LOW) && (B==LOW) )
cyclecounter[i] = 0;
else if ( (A==LOW) && (B==HIGH) )
cyclecounter[i] = 1;
else if ( (A==HIGH) && (B==HIGH) )
cyclecounter[i] = 2;
else if ( (A==HIGH) && (B==LOW) )
cyclecounter[i] = 3;

switch (cyclecounter[i]){
case (0) : {
if ( cyclecounterold[i] == 0){
;//Do nothing
}
else if ( cyclecounterold[i] == 1){
cycle[i]++;
Serial.print("C");
Serial.print(i);
Serial.print("-");
Serial.println(cycle[i]);
}
else if ( cyclecounterold[i] == 2){
Serial.println("Error reading from Encoder-");
}
else if ( cyclecounterold[i] == 3){
cycle[i]--;
Serial.print("C");
Serial.print(i);
Serial.print("-");
Serial.println(cycle[i]);
}
else
;//Serial.print("ERROR");
break;
}//end of case-0
case (1) : {
if ( cyclecounterold[i] == 0){
cycle[i]++;
Serial.print("C");
Serial.print(i);
Serial.print("-");
Serial.println(cycle[i]);
}
if ( cyclecounterold[i] == 2){
cycle[i]--;
Serial.print("C");
Serial.print(i);
Serial.print("-");
Serial.println(cycle[i]);
}
else if ( cyclecounterold[i] == 3){
Serial.println("Error reading from Encoder--");
}
else
;//Serial.print("ERROR");
break;
}
case (2) : {
if ( cyclecounterold[i] == 1){
cycle[i]--;
Serial.print("C");
Serial.print(i);
Serial.print("-");
Serial.println(cycle[i]);
}
else if ( cyclecounterold[i] == 2)
;
else if ( cyclecounterold[i] == 3){
cycle[i]++;
Serial.print("C");
Serial.print(i);
Serial.print("-");
Serial.println(cycle[i]);
}
else if ( cyclecounterold[i] == 0){
Serial.println("Error reading from Encoder---");
}
else
;//Serial.print("ERROR");
break;
}//end of case-2
case(3) : {
if (cyclecounterold[i] == 0){
cycle[i]--;
Serial.print("C");
Serial.print(i);
Serial.print("-");
Serial.println(cycle[i]);
}
else if (cyclecounterold[i] == 1){
Serial.println("Error reading from Encoder----");
}
else if ( cyclecounterold[i] == 2){
cycle[i]++;
Serial.print("C");
Serial.print(i);
Serial.print("-");
Serial.println(cycle[i]);
}
else if ( cyclecounterold[i] == 3)
;
else
;//Serial.print("ERROR");
break;
}//end of case-3
}

cyclecounterold[i] = cyclecounter[i];

}//end of for

}//end of checkEncoder()

>Meeting with my supervisor Mats Høvin, Summary

>Today I met my supervisor Mats Høvin(associated professor at IFI,UiO). Here comes a summary of what he thinks I should be focusing on :

  • Handshake protocol. I do not have this protocol & this is something that according to Mats, I better have it implemented in my code
  • Zero Positioning. My suggestion to this challenge is to save the current position all the time either at PC side or at the Arduino non-volatile memory.
  • Sending data packages back & forth in serial communication would possibly result in loss of data packages. How can my code handle this kind of problems ?
  • Error on startup, fix for it ? Is it a programming error, or a hardware error because of Noise on reading inputs from ports ???
  • Sending many bytes and the delays resulting by that
  • The speed control, should be handled in java or Arduino ??? Maybe fast in the beginning and slow down little by little while reaching the end of the axle
  • Play off modus & Should it be target based, or follow every detail from the log blindly ??? Discuss …
  • Camera candidates & streaming , but not image processing -> Intelligent cameras with output ports(how many???) for sending commands to Arduino according to the image processing done by camera itself.
  • Using WiFi tech & how ??? WiFly component ?
  • Programing a simulator in JAVA (xyz generation and visualization in JAVA)
  • PHP/JAVA Applet GUI & Streaming show on website
  • Multi Arduino card solutions ? Benefits and disadvantages ??? Discuss …
  • FPGA??? A possible solution instead of Arduino? Discuss …
  • Different methods to read data from encoders, External interruptions or software methods reading encoders value by analogRead() on loop frequence. Discuss based on Atmel/AVR architecture
  • Positioning in the room & semi-Kinect sensors

>Serial data transmission and problem with it being SLOW !!!

>A while ago I was facing a problem reading some inputs from Serial Communication(USB port) in Arduino. The Arduino would work perfect(read all the inputs from Serial Communication Window as planned) if I was having my debug print outs but not if I would remove them(they also could be substituted by Delays) !!! I later tried to find out about them and here was the answer :

“Serial data transmission is slow. The Serial.print statement takes time, which allows time for more data to arrive. You have two choices. Add a delay statement to the while loop, and hope all the data arrives in time is the first choice. The longer you waste time waiting for data, the better your chances of it all arriving in time.

The second choice is to add an end-of-packet marker, and keep appending to temp until that end of packet marker arrives. Only use the data in temp when the end of packet marker has arrived.

The delay masks the issue of not being able to read a complete packet in one pass. If the delay is too small, the whole packet will not arrive before the delay(s) expire. If the delay is too large, you are just wasting time.

The better approach is to add an end of packet marker to the packer, wo you can read the packet as quickly as possible..”

Source : http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1294185714/1#1