It's funny because I just learned linear algebra this year (I'm in Eighth Grade) so i could probably do it, and statistics is needed I should be able to figure it out. Thanks for the help. Oh and one more thing, I think I came up with a unique algorithm that works (I tested it out on a video game that I programmed). On the video game it sends "Ray" data (like a sensor) and I figured out how to move it around. I think I may have my algorithm set now in LUA but the next step is transferring. Thanks for the help because since I am only 14, I'll take the course this summer.
When I save my data, it goes to a uSD card. What protocol or saving method should I use. (like how should I save it in a file?)
Can anyone help me with the SD card datalog?
Can anyone help me with the SD card datalog?
There are examples for reading from and writing to an SD card that come with the SD library. How are your needs different from the examples?
What I meant was reading each line and isolating the info needed for a certain procedure.
isolating the info needed for a certain procedure.
You're going to have to be more specific
What I mean is, I want the Arduino to find lets say line 25 then pick out words and numbers out of a "sentence" written when the Arduino got all of the information from the outside world. The words and numbers it might pick out are like: wall=true or wall=false another is closest wall=155 or something similar to that. Thanks Simon.
It is time for you to get started writing some code for us to help you with. Make an effort, show some work, and we will help you get it together.
Start with the most basic parts first then, add features as you get each piece of code to work.
want the Arduino to find lets say line 25 then pick out words and numbers out of a "sentence" written when the Arduino got all of the information from the outside world. The words and numbers it might pick out are like: wall=true or wall=false another is closest wall=155 or something similar to that.
I don't really know what "line 25" represents in this context.
Normally, I'd advise representing information in as human-readable form as possible.
However, this is microcontroller territory, and they tend to be very constrained, so it's a balancing act between being able to read and interpret what your robot has mapped and done, versus code complexity and memory usage.
Consistency, I'd say, is the key, because you need to be able to unambiguously decode the information you have written.
What I meant by line 25 was in a .txt file, you make a grid by having evens x odds y (line numbers). This would make it easier for the microcontroller to find what is to be expected in the area or else it would change the statistic.
This is an idea that I came up with for my wavefrount code. It is all that I have right now and I am trying to get it to work right. Thanks.
// Includes
#include <Servo.h>
//#include "TimerThree.h"
// Constants
const int TurnAmount =1275;
const int GridSize =15;
const int StrightAmount=1900;
const int RobotWidth = 640;
int scan_one_cell=740;//lower number makes it see further
const float DegToRad = 0.0174532925;
const int numReadings =5;
// Sensor byte indices - offsets in packets 0, 5 and 6
#define SenBumpDrop 0
#define SenWall 1
#define SenCliffL 2
#define SenCliffFL 3
#define SenCliffFR 4
#define SenCliffR 5
#define Sen6Size 52
#define SenChAvailable 39
// Global variables
int NoSteps=0;
int timer_cnt = 0;
int timer_on = 0;
int sensors[Sen6Size];
int distance = 0;
signed long int angle = 0;
// Scanning Variables
unsigned long int scan_angle=750;//position of scanner, in units of servo command
unsigned int tmp=255;
unsigned int object_found=0;
int old_state=1;//records current pointed direction of robot: 1 is up, 2 is right, 3 is down, and 4 is left (clockwise)
int new_state=1;//required direction of robot
//X is vertical, Y is horizontal
int Map[GridSize][GridSize];
Servo myservo3;
Servo myservo2;
Servo myservo;
// Wave Front Variables
int nothing=0;
int wall=255;
int goal=1;
int robot=254;
//starting robot/goal locations
int robot_x=8;
int robot_y=8;
int goal_x=2;
int goal_y=2;
int cell_size=330;//the size of the robot
//Map locations
int x=0;
int y=0;
//temp variables
int counter=0;
//when searching for a node with a lower value
int minimum_node=250;
int min_node_location=0;
int reset_min=250;//anything above this number is a special item, ie a wall or robot
// Global variables
int turn_angle = 0;
int turn_dir = 1;
int turning = 0;
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
Serial.begin(9600);
myservo.attach(11); // attaches the servo on pin 9 to the servo object
//Timer3.initialize();
myservo2.attach(10);
myservo3.attach(9);
setupStepper();
for (int H=0; H<GridSize;H++)
{
for (int W=0; W<GridSize;W++)
{
Map[H][W]=0;
}
}
////////////////////Enter your code below this line////////////////////
//reset encoder function
angle = 0;
distance = 0;
//store robot location in Map
Map[robot_x][robot_y]=robot;
//store robot location in Map
Map[goal_x][goal_y]=goal;
// Drive around until a button or unsafe condition is detected
}
void loop()
{
while( (!sensors[SenCliffL])
&& (!sensors[SenCliffFL])
&& (!sensors[SenCliffFR])
&& (!sensors[SenCliffR])
&& (!sensors[SenChAvailable]) && Map[robot_x][robot_y]!=goal)//program ends when robot reaches goal
{
find_walls();
new_state=propagate_wavefront();
//////////////wavefront code//////////////
while(new_state!=old_state && new_state!=0)
{
//if not pointed in the right direction, rotate
if (abs(old_state - new_state) == 2)//rotate 180 degrees
{
rotate_CCW(180,250);
rotate_CW(90,150);
}
else if ((signed int)(old_state - new_state) == -1 || (signed int)(old_state - new_state) == 3)//rotate 90 degrees CW
rotate_CW(90,150);
else if ((signed int)(old_state - new_state) == 1 || (signed int)(old_state - new_state) == -3)//rotate 90 degrees CCW
rotate_CCW(90,150);
//make new state the old state
old_state=new_state;
//recheck with new location
find_walls();
//find new location to go to
new_state=propagate_wavefront();
}
//there is no solution
//Serial.println(new_state);
if (new_state==0)
{
delay(2500);
//reset the entire Map
clear_Map();
}
//go to new location
else//move if there is a solution, otherwise dont move forward
{
if (new_state==1)
robot_x--;
if (new_state==2)
robot_y++;
if (new_state==3)
robot_x++;
if (new_state==4)
robot_y--;
straight(cell_size,100);//distance, velocity
//update new location of robot
}
//make new state the old state
if(new_state!=0)
old_state=new_state;
}
if (Map[robot_x][robot_y]=goal)
{
if (goal_x=10)
goal_x=2;
else
goal_x=10;
Map[robot_x][robot_y]=robot;
//store robot location in Map
Map[goal_x][goal_y]=goal;
}
}
void rotate_CCW(signed long int angle_tmp, signed long int velocity)
{
turnRight();
// Timer3.attachInterrupt(MoveTurn, 900);
angle=0;
while(NoSteps!=0)
{
}
}
//rotate a certain angle - 100 = 90 degrees!
void rotate_CW(signed long int angle_tmp, signed long int velocity)
{
turnLeft();
// Timer3.attachInterrupt(MoveTurn, 900);
angle=0;
while(NoSteps!=0)
{
}
}
//drive straight function (use negative velocity to go in reverse)
void straight(signed long int distance_tmp, signed long int velocity)
{
stright();
// Timer3.attachInterrupt(MoveStright, 900);
// Serial.println("A"); // send the map to the serial port, for the processing
for (int H=0; H<GridSize;H++)
{
for (int W=0; W<GridSize;W++)
{
delay(9);
Serial.println(Map[H][W]);
}
}
while(NoSteps!=0)
{
}
}
const int LeftDir = 40;
const int LeftStep = 41;
const int RightDir = 42;
const int RightStep = 43;
void MoveStright()
{
if (NoSteps>StrightAmount-100)
{
// Timer3.stop();
// Timer3.attachInterrupt(MoveStrightSoft, 1500);
}
else
{
stepBoth();
NoSteps++;
}
}
void MoveStrightSoft()
{
if (NoSteps>StrightAmount)
{
// Timer3.stop();
NoSteps=0;
}
else
{
// Timer3.stop();
// Timer3.attachInterrupt(MoveStrightSoft, NoSteps);
stepBoth();
NoSteps++;
}
}
void MoveTurn()
{
if (NoSteps>TurnAmount)
{
// Timer3.stop();
NoSteps=0;
}
else
{
stepBoth();
NoSteps++;
}
}
void setupStepper()
{
/* pinMode(LeftDir, OUTPUT);
pinMode(LeftStep, OUTPUT);
pinMode(RightDir, OUTPUT);
pinMode(RightStep, OUTPUT);
digitalWrite(LeftDir, HIGH); //fwd
digitalWrite(RightDir, LOW);//fwd */
}
void stepBoth()
{
//digitalWrite(LeftStep, HIGH);
// digitalWrite(RightStep, HIGH);
myservo3.writeMicroseconds(1200);
myservo2.writeMicroseconds(1200);
Serial.println("step");
delay(1);
myservo3.write(90);
myservo2.write(90);
// digitalWrite(LeftStep, LOW);
// digitalWrite(RightStep, LOW);
}
void turnLeft()
{
myservo3.writeMicroseconds(1200);
myservo.writeMicroseconds(120);
Serial.println("left");
//digitalWrite(LeftDir, HIGH); //Bwd
// digitalWrite(RightDir, HIGH);//fwd
}
void turnRight()
{
myservo3.writeMicroseconds(1200);
myservo.writeMicroseconds(120);
Serial.println("right");
// digitalWrite(LeftDir, LOW); //fwd
// digitalWrite(RightDir, LOW);//Bwd
}
void stright()
{
Serial.println("fwd++");
myservo3.writeMicroseconds(1200);
myservo2.writeMicroseconds(1200);
//digitalWrite(LeftDir, HIGH); //fwd
// digitalWrite(RightDir, LOW);//fwd
}
//WAVEFRONT ALGORITHM
int propagate_wavefront()
{
//clear old wavefront
unpropagate();
counter=0;//reset the counter for each run!
//Serial.print("hi_5");
while(counter<50)//allows for recycling until robot is found
{
x=0;
y=0;
while(x<GridSize && y<GridSize)//while the Map hasnt been fully scanned
{
//if this location is a wall or the goal, just ignore it
if (Map[x][y] != wall && Map[x][y] != goal)
{
//a full trail to the robot has been located, finished!
if (min_surrounding_node_value(x, y) < reset_min && Map[x][y]==robot)
{
//finshed! tell robot to start moving down path
return min_node_location;
}
//record a value in to this node
else if (minimum_node!=reset_min)//if this isnt here, 'nothing' will go in the location
Map[x][y]=minimum_node+1;
}
//go to next node and/or row
y++;
if (y==GridSize && x!=GridSize)
{
x++;
y=0;
}
}
counter++;
}
return 0;
}
void unpropagate()//clears old path to determine new path
{
//stay within boundary
for(x=0; x<GridSize; x++)
for(y=0; y<GridSize; y++)
if (Map[x][y] != wall && Map[x][y] != goal) //if this location is something, just ignore it
Map[x][y] = nothing;//clear that space
//store robot location in Map
Map[robot_x][robot_y]=robot;
//store robot location in Map
Map[goal_x][goal_y]=goal;
}
//if no solution is found, delete all walls from Map
void clear_Map(void)
{
for(x=0;x<GridSize;x++)
for(y=0;y<GridSize;y++)
if (Map[x][y] != robot && Map[x][y] != goal)
Map[x][y]=nothing;
}
//this function looks at a node and returns the lowest value around that node
//1 is up, 2 is right, 3 is down, and 4 is left (clockwise)
int min_surrounding_node_value(int x, int y)
{
minimum_node=reset_min;//reset minimum
//down
if(x <(GridSize-1))//not out of boundary
if (Map[x+1][y] < minimum_node && Map[x+1][y] != nothing)//find the lowest number node, and exclude empty nodes (0's)
{
minimum_node = Map[x+1][y];
min_node_location=3;
}
//up
if(x > 0)
if (Map[x-1][y] < minimum_node && Map[x-1][y] != nothing)
{
minimum_node = Map[x-1][y];
min_node_location=1;
}
//right
if(y < (GridSize-1))
if (Map[x][y+1] < minimum_node && Map[x][y+1] != nothing)
{
minimum_node = Map[x][y+1];
min_node_location=2;
}
//left
if(y > 0)
if (Map[x][y-1] < minimum_node && Map[x][y-1] != nothing)
{
minimum_node = Map[x][y-1];
min_node_location=4;
}
return minimum_node;
}
//UPDATE Map BY SCANNING FOR WALLS
void find_walls(void)
{
//do not scan outside the border region
if((old_state==1 && robot_x==0) || (old_state==2 && robot_y==9) || (old_state==3 && robot_x==9) || (old_state==4 && robot_y==0))
return;
else
{
scan_angle=0;
//reset scanner
myservo.write(scan_angle);
delay(40);
object_found=0;
//do a full scan until something is sensed in the way
while(scan_angle <90 && object_found==0)
{
float volts;
float distance2 = 0;
float Wdistance2 = 0;
float distance3 = 0;
float Wdistance3 = 0;
for (int index = 0; index<numReadings;index++)
{ // take x number of readings from the sensor and average them
distance2 += (1000- analogRead(A1));
distance3 += (1000- analogRead(A0));
delay(10);
}
distance2 /=numReadings;
distance3 /=numReadings;
Wdistance3 = abs(distance3 *cos((scan_angle+90)*DegToRad));
Wdistance2 = abs(distance2 *cos(scan_angle*DegToRad));
/*
Serial.print(Wdistance2);
Serial.print(" ");
Serial.print(RobotWidth);
Serial.print(" ");
Serial.print(distance2);
Serial.print(" ");
Serial.println(scan_one_cell);
*/
if ((distance2 < scan_one_cell && Wdistance2 < RobotWidth )||(distance3 < scan_one_cell && Wdistance3 < RobotWidth ))//object found: add it to the Map
{
//account for angle of the robot wrt the Map, and stay in boundaries
if (old_state==1 && robot_x>0)
{
Map[robot_x-1][robot_y]=wall;
}
else if (old_state==2 && robot_y<(GridSize-1))
{
Map[robot_x][robot_y+1]=wall;
}
else if (old_state==3 && robot_x<(GridSize-1))
{
Map[robot_x+1][robot_y]=wall;
}
else if (old_state==4 && robot_y>0)
{
Map[robot_x][robot_y-1]=wall;
}
object_found=1;
}
//servo scan code
//-90 degrees at 300, lower goes CCW, 750 is centered, 1200 is far CW
myservo.write(scan_angle);
delay(12);
scan_angle++;
}
myservo.write(20);
if(object_found==0) //no object found, so clear it in the Map
{
//account for angle of the robot wrt the Map, and stay in boundaries
if (old_state==1 && robot_x>0)
Map[robot_x-1][robot_y]=nothing;
else if (old_state==2 && robot_y<(GridSize-1))
Map[robot_x][robot_y+1]=nothing;
else if (old_state==3 && robot_x<(GridSize-1))
Map[robot_x+1][robot_y]=nothing;
else if (old_state==4 && robot_y>0)
Map[robot_x][robot_y-1]=nothing;
}
}
//makes sure robot/goal location isnt replaced with a wall
//store robot location in Map
Map[robot_x][robot_y]=robot;
//store robot location in Map
Map[goal_x][goal_y]=goal;
}
It is all that I have right now and I am trying to get it to work right.
That code does something. You want it to do something. Whether those two things are the same thing only you and Madame Toussant can tell us, and she has weekends off. Her crystal ball has some fuzzy spots and her eyesight isn't all that good, either. So, it's probably best if you tell us.