Error in using IF statement - arduino-uno

I am new to Arduino. Currently I am working on a project that used phone gyro sensor to control the movement of RC car.This is my code so far;
char blueToothVal; //value sent over via bluetooth
char lastValue; //stores last state of device (on/off)
String str,x,y,z;
int value = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
if(Serial.available() >0 && value == 0 ) {
str= Serial.readStringUntil('A');
value = 1;
if(value == 1){
x= Serial.readStringUntil(';');
Serial.print("x = ");
Serial.print(x.toFloat());
Serial.print(" ");
y=Serial.readStringUntil(';');
Serial.print("y = ");
Serial.print(y.toFloat());
Serial.print(" ");
z= Serial.readStringUntil('A');
Serial.print("z = ");
Serial.print(z.toFloat());
Serial.println('\n');
value = 0;
delay(10);
}
}
if( y >=5 ){ //car forward
//CODING MOTOR HERE
}
if( y <= -3){ //car backward
//CODING MOTOR HERE
}
if( y >=5 && z >= 5){ //car steer to the left
//CODING MOTOR HERE
}
if( y >=5 && z <= -10){ //car steer to the right
//CODING MOTOR HERE
}
if( y <= -3 && z >=5){ //car reverse to the left
//CODING MOTOR HERE
}
if( y <= -3 && z <= -10){ //car reverse to the right
//CODING MOTOR HERE
}
if( x >= 330.00){ // only left tyre go forward
//CODING MOTOR HERE
}
if( x <= 300.00){ // only right tyre go forward
//CODING MOTOR HERE
}
}
I am using Arduino Uno R3 and DF robot motor shield. My problem here is that this coding cannot be compile. Can someone shed me some light on where is my mistake and what should I do??
The error message:
error: converting to 'const String' from initializer list would use explicit constructor 'String::String(int, unsigned char)'
indicating the line
if ( y >= 5 ){ //car forward

Compilation messages should be helpful.
First of them is:
sketch_may17a:37: error: converting to 'const String' from initializer list would use explicit constructor 'String::String(int, unsigned char)'
The reason is y is a String and you do with it numeric comparaisons (for example):
if( y >=5 )
Replace it by:
if( y.toInt() >= 5 )

Related

Image displaying using Arduino- Processing connection and ADXL345 sensor

I am working on an artistic project that includes an ADXL345 sensor (accelerometer), Arduino Uno R3 Board, Arduino IDE 2.0.3 and Processing 4.1.2.
I want Processing to display images randomly and continuously every time the values of the sensor that are received from the serial communication with the Arduino sketch, go x>5, x<-5, y.5, y.-5, z>1, z<-1.
UPDATE:
A friend helped me with some lines of code and now the image being displayed when I move the sensor.
CHALLENGE:
What I want to be able to do now is run the processing sketch ONCE and let the windows containing the images pop up, close down, open new windows and display new random images from my folder. For this process to repeat on itself so I don't have to run the sketch manually every time.
These are the codes that I am using in Arudino and Processing.
ARDUINO
void setup() {
// initialize serial communication at 9600 baud rate
Serial.begin(9600);
}
void loop() {
// send x, y, and z values over serial
int x = analogRead(A0);
int y = analogRead(A1);
int z = digitalRead(2);
Serial.print(x);
Serial.print(",");
Serial.print(y);
Serial.print(",");
Serial.println(z);
delay(1000);
}
& PROCESSING
import processing.serial.*;
Serial mySerial;
PImage fragment;
int rand;
void setup() {
size(1000, 500);
rand = int(random(0,133));
takerandomimage("C:/Users/user/Documents/Processing/Trial_300123/frag_" + nf(rand, 3) + ".jpg");
String portName = Serial.list()[0];
mySerial = new Serial(this, portName, 9600);
println("Serial port connected: " + portName);
loop();
}
void takerandomimage(String fn) {
fragment = loadImage(fn);
println(fragment);
}
void draw() {
background(255); //clears the screen
if (fragment.width>0 && fragment.height > 0){ //check if image has been loaded
String data = mySerial.readStringUntil('\n');
if (data != null && data != "\n" && data != " " && data != "\r" && data != "\t") {
println("Data received: " + data);
String[] values = data.split(" ",0);
int counter = 0;
int x = 0;
int y = 0;
int z = 0;
for(String w :values){
System.out.println(w);
if (counter == 1)
x = int(w);
if ( counter == 4)
y = int(w);
if ( counter == 7)
z = int(w);
counter++;
}
println(x);
println(y);
println(z);
if (x < 0 || y > 0 || z > 0) {
takerandomimage("C:/Users/user/Documents/Processing/Trial_300123/frag_" + nf(rand, 3) + ".jpg");
image(fragment, 0,0);
delay(1000);
}
}
}
}
Thank you!!
So many things are right with your code (and question)(+1):
your question mentions version of the Arduino/Processing used, Arduino board, sensor and also includes minimal code focused on the issue
checking if data is not null
checking if the split array is right length, etc.
You are so close !
There is one issue throwing off parsing:
your Processing code assumes you have the x, y, z values one line: String data = mySerial.readStringUntil('\n');
your Arduino code is printling mulitple lines instead of one(e.g. Serial.println(x); instead of Serial.print(x))
to double check, you would see x, y, z values (as well as the two "," symbols) in Serial Monitor on separate lines each (instead of all on one line)
I suspect the intention was to use println() only on the last line:
void setup() {
// initialize serial communication at 9600 baud rate
Serial.begin(9600);
}
void loop() {
// send x, y, and z values over serial
int x = analogRead(A0);
int y = analogRead(A1);
int z = digitalRead(2);
Serial.print(x);
Serial.print(",");
Serial.print(y);
Serial.print(",");
Serial.println(z);
delay(1000);
}
(The above should print 3 values separated by "," on a single line. Double check if z should be a digitalRead(2) (returning 1 or 0) reading on pin 2 on your Arduino or analogRead(A2) (returning 0 to 1023) reading analog pin A2.)
Update
Another idea is move the accelerometer conditions in the Arduino code and simply output a single byte/character ('i' for example) when you want to trigger loading a random image in Processing.
Here's a rough / untested example:
void setup() {
// initialize serial communication at 9600 baud rate
Serial.begin(9600);
}
void loop() {
// send x, y, and z values over serial
int x = analogRead(A0);
int y = analogRead(A1);
int z = digitalRead(2);
// if the right motion is picked up, send 'i' to Processing to load a random image
if (x > 5 || y > 5 || z > 0) {
Serial.print('i');
}
delay(1000);
}
Note that with the 1000 ms (1s) delay means you can't trigger an image change faster than that. Adjust the delay as needed.
Additionally you say you want to trigger the change when accelerometer values meet these conditions:
x>5, x<-5, y.5, y.-5, z>1, z<-1.
If so, you might want to change:
if (x > 5 || y > 5 || z > 0)
to
if (abs(x) > 5 || abs(y) > 5 || abs(z) > 0)
(where abs() returns the absolute value (e.g. 5 remains 5, but -5 becomes 5))
Hopefully the values you selected make sense for the motion you're trying to capture with the accelerometer (otherwise the Serial Plot tool in Arduino can be helpful).
If you move the condition to Arduino it simplifies the Processing code as you don't need to wait for a full string to parse into an array: you can read just one character.
import processing.serial.*;
Serial mySerial;
PImage fragment;
void setup() {
size(1000, 500);
loadRandomImage();
String portName = Serial.list()[0];
mySerial = new Serial(this, portName, 9600);
}
void loadRandomImage() {
int rand = int(random(0,133));
String filename = "frag_" + nf(rand, 3) + ".jpg"
fragment = loadImage(fn);
}
void draw() {
// if there is a serial data
if(mySerial.available > 0){
// read one byte/char (mask (&) because byte range is -127 to 127 in java, but 0 to 255 in c++)
char data = mySerial.read() & 255;
// optional: print serial to debug
println("received from Arduino", data);
// if the expect char (i) was received, load random image
if(data == 'i'){
loadRandomImage();
}
}
background(255); //clears the screen
if (fragment.width>0){ //check if image has been loaded
image(fragment, 0, 0);
}
}
Notice a few other minor changes:
I've renamed takerandomimage to loadRandomImage() and changed it so each time the function gets called it generates the random number and loads the random image
whenever the 'i' character is received from Ardiuno a new random is loaded
whatever random image has been set gets displayed continuously (decoupling image display from reading serial data). Before you only loaded and displayed an image if the right serial data came through).

How to code a servomotor with two buttons in arduino?

I wanted to make a servomotor oscilate between 0-90 degrees when i push a button, but when i push another one, it stops oscillating and then remains in its latest position.
i started with this:
#include <Servo.h>
Servo myservo;
int pos = 0;
const int button1 = 5;
const int button2 = 6;
int lastpos = pos;
void setup() {
myservo.attach(3);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
}
void loop() {
if(digitalRead(button1) == HIGH)
{for(pos = 0; pos <= 90; pos += 1)
{myservo.write(pos);
for(pos = 90; pos >= 0; pos -= 1)
{myservo.write(pos);
delay(36);
} } if(digitalRead(button2) == HIGH){ myservo.write(lastpos);}}}
To start, take a look at how to format code inside a question. It makes it a lot easier to read and help you out. See below for how I formatted for the site, but also readability.
Servo myservo;
int pos = 0;
const int button1 = 5;
const int button2 = 6;
int lastpos = pos;
void setup() {
myservo.attach(3);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
}
void loop() {
if(digitalRead(button1) == HIGH) {
for(pos = 0; pos <= 90; pos += 1) {
myservo.write(pos);
for(pos = 90; pos >= 0; pos -= 1) {
myservo.write(pos);
delay(36);
}
}
if(digitalRead(button2) == HIGH) {
myservo.write(lastpos);
}
}
}
There are several issues with your code based on your description of what you are trying to achieve. First, let's start with the button presses. You are ready the button state, but your code will only detect the button if it is pressed at the exact moment you are doing the digital read. Here's a good resource for reading up on how to properly implement buttons on Arduino: https://www.logiqbit.com/perfect-arduino-button-presses
The second objective is to have the servo sweep back and forth, but stop when you press a button. Your for loops won't let that happen. As currently written, you will always do a sweep to one end and back and then check the next button.
You should update the position of the servo once each time through the loop so you can check on the status of the buttons. In pseudo-code, what I suggest you do is:
void loop() {
//Check button statuses
if(button1), start sweep
if(button2), stop sweep
//Update sweep position
if(ascending && pos < 90) {
//You should be increasing in angle and you haven't reached 90 yet
ascending = TRUE;
pos += 1
myservo.write(pos);
delay(36); //Or whatever delay you need for the servo
} else if(pos > 0) {
//You already reached 90 and are coming back down to 0
ascending = FALSE;
pos -= 1;
delay(36);
}

RPG style sprite movement with SDL2 using Crystal

I'm using SDL2 with Crystal to make a 16bit RPG style tile-based game. I've seen this question asked a ton, but even with all the answers I've come across, I'm still not getting the movement I'm looking for. Have you ever played Final Fantasy IV, V, or VI on the SNES? I'm looking for movement like that. No diagonal, character is always over a tile, and never stops between 2 tiles.
# main game loop
loop do
ticks = Time.monotonic.milliseconds / 1000.0
case event = SDL::Event.poll
when SDL::Event::Keyboard
case event.sym
when .right?
character.move_right(ticks)
end
end
character.draw(renderer)
renderer.present
#other code handling break and stuff omitted
end
# character.cr
VELOCITY = 100
def move_right(delta_ticks)
#direction_facing = "east"
#x += VELOCITY * delta_ticks
end
def draw(renderer)
sprite = #directions[#direction_facing]
renderer.copy(sprite, dstrect: SDL::Rect[#x.to_i, #y.to_i, 64, 64])
end
The way my current movement works, the character starts walking slow, then picks up speed then drops back down to walking slow like it's shifting gears or something. I know my line #x += VELOCITY * delta_ticks is wrong, but I wasn't able to find one that worked how I wanted. This also doesn't take in to account stopping directly over a tile (in this case 64x64).
EDIT: I've tried to transpose the suggestion #genpfault gave. It still doesn't do what I want, but since I don't know C++, I may have missed some stuff. That code update is here
Make a little "tasklet" helper (I know zero about Crystal; in C++ I'd just have this be a class/struct with member data & functions) that encapsulates the character's current tile x/y position (and fine, sub-tile x/y position)
When you handle the left/right/up/down input, check if a current tasklet is still doing its thing; if not, make a new tasklet with the desired direction
Each frame while a tasklet is active, process it: increment/decrement (1px/frame? up to you) the character's fine x/y position until it hits the goal tile position; if the tasklet hits the goal position this frame, remove it (and update the character's tile position)
This way you prevent new input from interfering with character motion while it's in progress, as well as smoothly animating tile transitions.
Something like this:
#include <SDL2/SDL.h>
#include <memory>
struct Character
{
int m_TileX;
int m_TileY;
int m_FineX; // in 16ths of a tile
int m_FineY; // in 16ths of a tile
};
class ITask
{
public:
virtual ~ITask() {};
// override & return true to indicate this task is done
virtual bool Run() = 0;
};
class CharacterAnimator : public ITask
{
public:
CharacterAnimator( Character& c, int dx, int dy )
: m_C( c )
, m_Dx( dx )
, m_Dy( dy )
{}
~CharacterAnimator() override {}
bool Run() override
{
m_C.m_FineX += m_Dx;
m_C.m_FineY += m_Dy;
bool done = false;
if( m_C.m_FineX <= -16 ) { m_C.m_TileX--; m_C.m_FineX = 0; done = true; }
if( m_C.m_FineY <= -16 ) { m_C.m_TileY--; m_C.m_FineY = 0; done = true; }
if( m_C.m_FineX >= 16 ) { m_C.m_TileX++; m_C.m_FineX = 0; done = true; }
if( m_C.m_FineY >= 16 ) { m_C.m_TileY++; m_C.m_FineY = 0; done = true; }
return done;
}
private:
Character& m_C;
int m_Dx;
int m_Dy;
};
int main( int argc, char** argv )
{
SDL_Init( SDL_INIT_EVERYTHING );
SDL_Window * window = SDL_CreateWindow
(
"SDL2",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
640, 480,
SDL_WINDOW_SHOWN
);
SDL_Renderer* renderer = SDL_CreateRenderer
(
window,
0,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
);
SDL_RenderSetLogicalSize( renderer, 320, 240 );
Character c;
c.m_TileX = 9;
c.m_TileY = 7;
c.m_FineX = 0;
c.m_FineY = 0;
std::unique_ptr< ITask > movementTask;
bool running = true;
while( running )
{
if( movementTask && movementTask->Run() )
{
movementTask.reset();
}
SDL_Event ev;
while( SDL_PollEvent( &ev ) )
{
if ( ev.type == SDL_QUIT )
running = false;
if( ev.type == SDL_KEYUP && ev.key.keysym.sym == SDLK_ESCAPE )
running = false;
if( ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_UP && !movementTask )
movementTask = std::unique_ptr< ITask >( new CharacterAnimator( c, 0, -1 ) );
if( ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_DOWN && !movementTask )
movementTask = std::unique_ptr< ITask >( new CharacterAnimator( c, 0, 1 ) );
if( ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_LEFT && !movementTask )
movementTask = std::unique_ptr< ITask >( new CharacterAnimator( c, -1, 0 ) );
if( ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_RIGHT && !movementTask )
movementTask = std::unique_ptr< ITask >( new CharacterAnimator( c, 1, 0 ) );
}
SDL_SetRenderDrawColor( renderer, 0, 0, 0, 255 );
SDL_RenderClear( renderer );
// draw character
SDL_SetRenderDrawColor( renderer, 255, 0, 0, 255 );
SDL_Rect r =
{
c.m_TileX * 16 + c.m_FineX,
c.m_TileY * 16 + c.m_FineY,
16,
16
};
SDL_RenderFillRect( renderer, &r );
SDL_RenderPresent( renderer );
}
SDL_DestroyRenderer( renderer );
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}

IR Receiver RC5 with Pic12F1572

I am building an IR Receiver with PIC12F1572 with receiver module TSOP2438
My objective of this project is to receive a data by remote control and send it to PC via UART..
I have done the code and I am testing it I can send the normal value through the UART but Somewhereis wrong so that I can not receive the hex values regarding the commands of remote control
Can anyone see my code and tell where I am goping wrong?
Here is my code
void main(void)
{
OSCILLATOR_Initialize(); // 0x78 for Fosc = 16Mhz
PIN_MANAGER_Initialize(); //All port pins Digital and input
EUSART_Initialize();
INTCONbits.IOCIF = 0; // Interrupt on-change Flag
INTCONbits.PEIE = 1; //SEt Peripheral Interrupt
INTCONbits.GIE = 1; //Set Global Interrupt
//while(!OSCSTATbits.HFIOFS); //Check here or wait here to OSC stable/ 0.5% accuracy
TRISAbits.TRISA2 = 1; //Configure R1 as input
// uint16_t Input_buffer [20];
EUSART_Write(0x40); // 0x40 = # some flag
while(1)
{
count = 0;
//while((IR_PIN)); //IR_PIN receives an IR signal its output pin goes from logic 1 to logic 0
//which causes the microcontroller to start reading the IR signal using the function. decode()
EUSART_Write(0x41);
//while(IR_PIN);
if(Decode()) //check if RC5 decoding- new data is arrived
{
EUSART_Write(0x42);
toggle_bit = bit_test(IR_Code, 11);
address = (IR_Code >> 6) & 0x1F;
command = IR_Code & 0x3F;
EUSART_Write(toggle_bit);
EUSART_Write(address);
EUSART_Write(command);
EUSART_Write(0x43);
}
}
}
/*----------*/
uint8_t Measure_space()
{
TMR0_Initialize();
while(IR_PIN && (count < 2000))
count = TMR0_ReadTimer(); //Read timer value and store it in count value
if((count > 1999) || (count < 700))
return 0; //0 = If width is out of range
if(count > 1200)
return 1; //1 = If width is long
else
return 2; //2 = If the width is short
}
uint8_t Decode()
{
uint8_t i = 0, check;
mid1:
check = Measure_Pulse();
if(check == 0)
return FALSE;
bit_set(IR_Code, 13 - i);
i++;
if(i > 13)
return TRUE;
if(check == 1)
goto mid0;
else
goto start1;
mid0:
check = Measure_space();
if((check == 0) && (i != 13))
return FALSE;
bit_clear(IR_Code, 13 - i);
i++;
if(i > 13) return TRUE;
if(check == 1)
goto mid1;
else
goto start0;
start1:
check = Measure_space();
if(check != 2)
return FALSE;
goto mid1;
start0:
check = Measure_Pulse();
if(check != 2)
return FALSE;
goto mid0;
}
I think this is because you are sending Hex value without converting to string. If you want to print this Hex value in PC terminal, First you have to convert it to ASCII string.

How to set up if statements so that loop goes forward and then in reverse? Processing

int x = 31;
int y = 31;
int x_dir = 4;
int y_dir = 0;
void setup ()
{
size (800, 800);
}
void draw ()
{
background (150);
ellipse (x,y,60, 60);
if (x+30>=width)
{
x_dir =-4;
y_dir = 4;
}
if (y+30>=height)
{
x_dir=4;
y_dir = 0;
}
if (x+30>=width)
{
x_dir = -4;
}
x+=x_dir;
y+=y_dir;
println(x,y);
}
Hi,
I have to create this program in processing which produces an animation of a ball going in a Z pattern (top left to top right, diagonal top right to bottom left, and then straight from bottom left to bottom right) which then goes backwards along the same path it came.
While I have the code written out for the forward direction, I don't know what 2 if or else statements I need to write for the program so that based on one condition it goes forwards, and based on another condition it will go backwards, and it will continue doing so until it terminates.
If I am able to figure out which two if statements I need to write, all I need to do is copy and reverse the x_dir and y_dir signs on the forward loop.
There are a ton of different ways you can do this.
One approach is to keep track of which "mode" you're in. You could do this using an int variable that's 0 when you're on the first part of the path, 1 when you're on the second part of the path, etc. Then just use an if statement to decide what to do, how to move the ball, etc.
Here's an example:
int x = 31;
int y = 31;
int mode = 0;
void setup ()
{
size (800, 800);
}
void draw ()
{
background (150);
ellipse (x, y, 60, 60);
if (mode == 0) {
x = x + 4;
if (x+30>=width) {
mode = 1;
}
} else if (mode == 1) {
x = x - 4;
y = y + 4;
if (y+30>=height) {
mode = 2;
}
} else if (mode == 2) {
x = x + 4;
if (x+30>=width) {
mode = 3;
}
} else if (mode == 3) {
x = x - 4;
y = y - 4;
if (y-30 < 0) {
mode = 2;
}
}
}
Like I said, this is only one way to approach the problem, and there are some obvious improvements you could make. For example, you could store the movement speeds and the conditions that change the mode in an array (or better yet, in objects) and get rid of all of the if statements.

Resources