Controlling a stepper motor using Arduino and serial - c++

I would like to create an Arduino program that receives (via serial) only two commands: "1" and "2".
Through these commands, I would like Arduino to operate a stepper motor like this:
If I write "1" on the serial, the motor must move clockwise
If I write "2" on the serial, the motor must move counterclockwise
I have already written a code that only works halfway:
#include <Stepper.h>
const int stepsPerRevolution = 1500;
int incomingByte;
Stepper myStepper(stepsPerRevolution, 11, 9, 10, 8);
void setup() {
myStepper.setSpeed(20);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
Serial.print("I received: ");
Serial.println(incomingByte);
if (incomingByte = "1") {
Serial.println("Moving clockwise...");
myStepper.step(stepsPerRevolution);
delay(500);
}
if (incomingByte = "2") {
Serial.println("Moving counterclockwise...");
myStepper.step(-stepsPerRevolution);
delay(500);
}
}
}
When active, the program waits for the commands on the serial port and manages to read them. The problem is that in both cases (1 and 2) the motor moves first clockwise and then subsequently anticlockwise and it is not the result I would like to achieve.
Can you give me a hand in this endeavor?

Use comparison operation instead of assignment operator like so.Double quote around 1 is not required since the variable is int datatype. Use an else command after the first if statement so that only one of the commands will operate.
const int stepsPerRevolution = 1500;
int incomingByte;
Stepper myStepper(stepsPerRevolution, 11, 9, 10, 8);
void setup() {
myStepper.setSpeed(20);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
Serial.print("I received: ");
Serial.println(incomingByte);
if (incomingByte == 49) {
Serial.println("Moving clockwise...");
myStepper.step(stepsPerRevolution);
delay(500);
}
else
if (incomingByte == 50) {
Serial.println("Moving counterclockwise...");
myStepper.step(-stepsPerRevolution);
delay(500);
}
}
}

Ok, here is the final code; all working!
#include <Stepper.h>
const int stepsPerRevolution = 1500;
int incomingByte;
Stepper myStepper(stepsPerRevolution, 11, 9, 10, 8);
void setup() {
myStepper.setSpeed(20);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
Serial.print("I received: ");
Serial.println(incomingByte);
if (incomingByte == 49) {
Serial.println("Moving clockwise...");
myStepper.step(stepsPerRevolution);
delay(500);
}
else
if (incomingByte == 50) {
Serial.println("Moving counterclockwise...");
myStepper.step(-stepsPerRevolution);
delay(500);
}
}
}

Related

Shift Register reacting to shiftout function incorrectly

I am new to this shift register. So i created a online simulation of the shift register that hook up to 8 LEDs, the ol' 8bit translate to 8 LED experiment. My design is that when i entered a character like "a" into the serial monitor, it will show in the result in code like 100000, and it should shown in the LEDs too(the sixth LED should light up).
char character;
byte input = 0b01;
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
byte input = 0b01;
if (Serial.available() > 0) {
character = Serial.read();
if (character == 'a') {
Serial.print("character received: ");
Serial.println(character);
for (int i = 0; i < 5; i++) {
updateShiftRegister(input);
input = input << 1;
delay(100);
}
Serial.print("Input: ");
Serial.print(input, BIN);
Serial.println();
} else {
Serial.print("Please retry.\n");
}
}
}
void updateShiftRegister(byte input) {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, input);
digitalWrite(latchPin, HIGH);
}
Problem is when i run the thing, the result is alright but the shift register in the simulation is wack. Every LEDs turn on,
I found the shiftout function is main cause of this, any idea why it is causing every LED to light up?

Connecting an Arduino ESP32 microcontroller to javafx via PacketSender

We have built a drone controller using C++ and an Arduino ESP32 module. We have achieved connection to a Tello Drone and can control it successfully. However, now we want to connect our controller to a javafx program that receives input and then draws on a canvas in scene builder.
Meanwhile the problem is that we can't seem to connect our controller through PacketSender. We have attached our code, including the previous built that enabled connection with a drone.
The big question is how to send the messages between two programs and initiate our virtual depiction of our drone on a canvas - instead of the actual physical one.
The issue seems to be in case 1, line 190, where we connected controller to actual drone, but now have to write up a new connection somehow.
#include <Arduino.h>
#include "WiFi.h"
#include "AsyncUDP.h"
const char * ssid = "OnePlus 7 Pro";
const char * password = "hej12345";
//Connect button variables (Command)
int inPinLand = 18;
int valLand = 0;
//Ultra sonic sensor variables
#define trigPin 2
#define echoPin 21
//Land button variables (Land)
int inPin = 25;
int val = 0;
//Instantiate specific drone
const char * networkName = "TELLO-59F484";
const char * networkPswd = "";
//IP address to send UDP data to:
// either use the ip address of the server or
// a network broadcast address
const char * udpAddress = "10.60.0.227";
const int udpPort = 7000;
boolean connected = false;
char fromTello[256];
unsigned long timer;
//static const byte glyph[] = { B00010000, B00110100, B00110000, B00110100, B00010000 };
//static PCD8544 lcd;
uint8_t state = 0;
//Controller movement variables
int pitch = 0;
int roll = 0;
int yaw = 0;
int throttle = 0;
char cmd[256];
AsyncUDP udp;
void setup() {
Serial.begin(9600);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed");
while (1) {
delay(1000);
}
}
pinMode(5, OUTPUT);
digitalWrite(5, HIGH);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(inPin, INPUT);
pinMode(inPinLand, INPUT);
//LCD screen initialization
//lcd.begin(84, 48);
Serial.begin(9600);
//pinMode(trigPin, OUTPUT);
//pinMode(echoPin, INPUT);
//pinMode(BL, OUTPUT);
//digitalWrite(BL, HIGH);
if (udp.listen(7000)) {
Serial.print("UDP Listening on IP: ");
Serial.println(WiFi.localIP());
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("UDP Packet Type: ");
Serial.print(packet.isBroadcast()
? "Broadcast"
: packet.isMulticast() ? "Multicast" : "Unicast");
Serial.print(", From: ");
Serial.print(packet.remoteIP());
Serial.print(":");
Serial.print(packet.remotePort());
Serial.print(", To: ");
Serial.print(packet.localIP());
Serial.print(":");
Serial.print(packet.localPort());
Serial.print(", Length: ");
Serial.print(packet.length());
Serial.print(", Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
// reply to the client/sender
packet.printf("Got %u bytes of data", packet.length());
});
}
// Send unicast
// udp.print("Hello Server!");
// udp.
}
//WiFi connection function
void connectToWiFi(const char * ssid, const char * pwd) {
Serial.println("Connecting to WiFi network: " + String(ssid));
// delete old config
WiFi.disconnect(true);
//Initiate connection
WiFi.begin(ssid, pwd);
Serial.println("Waiting for WIFI connection...");
}
//Drone connection function
void TelloCommand(char *cmd) {
//only send data when connected
if (connected) {
//Send a packet
//udp.beginPacket(udpAddress, udpPort); OUTDATED has new name with ASync
udp.printf(cmd);
//udp.endPacket(); OUTDATED has new name with ASync
Serial.printf("Send [%s] to Tello.\n", cmd);
}
}
void sendMessage(String msg){
udp.writeTo((const uint8_t *)msg.c_str(), msg.length(),
IPAddress(169, 254, 107, 16), 4000);
}
void loop() {
delay(5000);
// Send broadcast on port 4000
udp.broadcastTo("Anyone here?", 4000);
// Serial.println("waiting for udp message...");
int x = 100;
int y = 100;
sendMessage("init " + String(x) + " " + String(y));
}
void loop() {
long duration, distance;
val = digitalRead(inPin); // read input value
//Ultra sonic sensor
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) / 29.1;
//LCD screen line 2
// lcd.setCursor(0, 1);
// lcd.print(distance, DEC);
//State machine that connects the drone to WiFi and the controller
switch (state)
{
case 0: //Idle not connected
//LCD screen line 1
//lcd.setCursor(0, 0);
//lcd.print("Controller");
if (val == HIGH)
{
state = 1;
connectToWiFi(networkName, networkPswd);
timer = millis() + 5000;
}
break;
case 1: //Trying to connect
if (WiFi.status() == WL_CONNECTED)
{
Serial.print("Connected to: ");
Serial.println(networkName);
udp.begin(WiFi.localIP(), udpPort);
connected = true;
TelloCommand("command");
timer = millis() + 2000;
state = 2;
}
if (millis() > timer)
{
state = 0;
}
break;
case 2: //Connected on ground
//lcd.setCursor(0, 0);
//lcd.print("Connected ");
if (WiFi.status() != WL_CONNECTED)
{
WiFi.disconnect(true);
Serial.println("Disconnected");
state = 0;
}
if (distance < 10)
{
TelloCommand("takeoff");
timer = millis() + 1000;
state = 3;
Serial.println("takeoff");
}
break;
case 3: //In air
//lcd.setCursor(0, 0);
//lcd.print("In air ");
if (millis() > timer)
{
timer = millis() + 20;
pitch = map(analogRead(34) - 1890, -2000, 2000, -100, 100);
roll = map(analogRead(35) - 1910, -2000, 2000, -100, 100);
throttle = map(analogRead(33) - 1910, -2000, 2000, -100, 100);
yaw = map(analogRead(32) - 1910, -2000, 2000, -100, 100);
sprintf(cmd, "rc %d %d %d %d", roll, pitch, throttle, yaw);
TelloCommand(cmd);
}
if (val == HIGH) {
TelloCommand("land");
timer = millis() + 1000;
state = 0;
Serial.println("land");
}
break;
}
delay(200);
}

Serial Communication freezes with BMP180 and Arduino Mega

I recently bought an ELEGO Mega 2560, or in other words an Arduino Mega. I bought a bmp180 sensor as well. I connected the bmp in this fashion, VCC - 3.3v, GND - GND, SCL - 21, SDA - 20. I uploaded a simple code which just displayes altitude. When I go to the Serial Monitor to view the results, nothing pops up. It is suppose to say BMP init success if it connects, and fail if it doesn't. When I go to the monitor, it just doens't say anything. When I disconnect the sensor, it says fail. It appears as if the Serial Monitor just freezes. Also a headsup, my code is very messy, I'm sorry if it's hard to keep up.
#include <Wire.h>
#include <SFE_BMP180.h>
SFE_BMP180 bmp180;
float Po = 1014.9;
#define ledPin 7
#define TransmitPin 5
//int Altitude = 5;
int sendValue;
String incomingString;
unsigned long lastTransmission;
const int interval = 1000;
void setup() {
Wire.begin();
pinMode(ledPin, OUTPUT);
pinMode(2, INPUT);
pinMode(10, OUTPUT);
pinMode(TransmitPin, OUTPUT);
bool success = bmp180.begin();
Serial.begin(115200);
if (success) {
Serial.println("BMP180 init success");
}
else
Serial.println("fail");
}
void loop() {
sendValue = digitalRead(29);
if (sendValue == HIGH) {
if (millis() > lastTransmission + interval) {
Serial.println("AT+SEND=1,8,Return");
digitalWrite(TransmitPin, HIGH);
delay(100);
digitalWrite(TransmitPin, LOW);
lastTransmission = millis();
}
}
if (Serial.available()) {
incomingString = Serial.readString();
if (incomingString.indexOf("Testing!") > 0) {
digitalWrite(10, HIGH);
delay(100);
digitalWrite(10, LOW);
}
}
char status;
double T, P, alt;
bool success = false;
status = bmp180.startTemperature();
if (status != 0) {
delay(1000);
status = bmp180.getTemperature(T);
if (status != 0) {
status = bmp180.startPressure(3);
if (status != 0) {
delay(status);
status = bmp180.getPressure(P, T);
if (status != 0) {
if (millis() > lastTransmission + interval) {
alt = bmp180.altitude(P, Po);
Serial.print("AT+SEND=1,8,");
int altAsFoot = alt * 3.281;
Serial.println(altAsFoot);
digitalWrite(TransmitPin, HIGH);
delay(100);
digitalWrite(TransmitPin, LOW);
}
for (int i = 0; i < 1800; i++) {
delay(1);
if (Serial.available()) {
incomingString = Serial.readString();
if (incomingString.indexOf("+OK") > 0) {
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
}
if (incomingString.indexOf("Testing!") > 0) {
digitalWrite(10, HIGH);
delay(100);
digitalWrite(10, LOW);
}
}
}
}
}
}
}
}
Turns out it was a hardware issue. I had ground shorted to SDA. I'm assuming the same will happen if it's shorted to SCL. Make sure both SDA and SCL aren't shorted to each other or ground.

strcmp brakes Arduino sketch

For a school project, I'm using an Arduino Uno together with a Parallax RFID, a LCD screen and an esp8226-wifi module.
I'm trying to compare the scanned tag with the tags in the database and send the name of the tag owner to a terminal in the Blynk app. Everything works just fine until I put in the function that compares the tags. If I do that, everything stops working, even the code in the setup() part. How can I fix this?
I think the problem has somehing to do with the strcmp.
/* Libraries that need to be manually installed:
Blynk libraries: https://github.com/blynkkk/blynk-library/releases/download/v0.5.0/Blynk_Release_v0.5.0.zip
LiquidCrystal_I2C library: https://cdn.instructables.com/ORIG/FVH/K8OQ/J8UH0B9U/FVHK8OQJ8UH0B9U.zip
*/
#define BLYNK_PRINT Serial
#include <SoftwareSerial.h>
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//Setting up the Blynk wifi connection
#define ESP8266_BAUD 9600
char auth[] = "87b00838cd834e4e87a0422265cc7a9e";
char ssid[] = "bbox2-56b2";
char pass[] = "91C2D797F6";
//Setting up the virtual pins
WidgetTerminal terminal(V1);
BLYNK_WRITE(V1){}
//Setting up the RFID
#define RFIDEnablePin 8
#define RFIDSerialRate 2400
String RFIDTAG=""; //Holds the RFID Code read from a tag
String DisplayTAG = ""; //Holds the last displayed RFID Tag
//Setting up the LCD
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
//Setting up the serial connection
SoftwareSerial EspSerial(2, 3);
ESP8266 wifi(&EspSerial);
void setup()
{
//Serial communication
Serial.begin(RFIDSerialRate);
EspSerial.begin(ESP8266_BAUD);
Serial.begin(RFIDSerialRate);
delay(10);
//Blynk setup
Blynk.begin(auth, wifi, ssid, pass);
//LCD setup
lcd.begin(16,2);//16 kolommen, 2 rijen
lcd.backlight();
//RFID setup
pinMode(RFIDEnablePin,OUTPUT);
digitalWrite(RFIDEnablePin, LOW);
terminal.println("Terminal printing succesfull");
terminal.flush();
}
void loop()
{
if(Serial.available() > 0)
{
ReadSerial(RFIDTAG);
}
if(DisplayTAG!=RFIDTAG)
{
DisplayTAG=RFIDTAG;
// PROBLEM STARTS HERE
//Tag database
char tags[10][10] = {"6196", "6753", "5655", "69EC", "9FFC"};
char owners[10][30] = {"per1", "per2", "per3", "per4", "per5"};
int i = 0;
int j = 0;
int ownerLength = 0;
char lastTag[10];
RFIDTAG.toCharArray(lastTag, 10);
while (i < 10)
{
if (strcmp(tags[i], lastTag) == 0)
{
ownerLength = strlen(owners[i]);
while (j < ownerLength)
{
terminal.print(owners[i][j]);
}
terminal.println("has entered the parking\n\r");
terminal.flush();
break;
}
i++;
}
i = 0;
j = 0;
//PROBLEM ENDS HERE
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Last tag:");
lcd.setCursor(0,1);
lcd.print(RFIDTAG);
digitalWrite(RFIDEnablePin, HIGH);
delay(1000);
digitalWrite(RFIDEnablePin, LOW);
}
Blynk.run();
}
//Function for reading the tag
void ReadSerial(String &ReadTagString)
{
int bytesread = 0;
int val = 0;
char code[10];
String TagCode="";
if(Serial.available() > 0)
{
if((val = Serial.read()) == 10)
{
bytesread = 0;
while(bytesread<10) // Reads the tag code
{
if( Serial.available() > 0)
{
val = Serial.read();
if((val == 10)||(val == 13)) // If header or stop bytes before the 10 digit reading
{
break; // Stop reading
}
code[bytesread] = val; // Add the digit
bytesread++; // Ready to read next digit
}
}
if(bytesread == 10) // If 10 digit read is complete
{
for(int x=6;x<10;x++) //Copy the Chars to a String
{
TagCode += code[x];
}
ReadTagString = TagCode; //Returns the tag ID
while(Serial.available() > 0) //Burn off any characters still in the buffer
{
Serial.read();
}
}
bytesread = 0;
TagCode="";
}
}
}

Arduino clear buffer

#include <stdio.h>
#define LED 13
void setup() {
pinMode(LED, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (Serial.available() == 4) {
char command[5];
for (int i = 0; i < 4; i++) command[i] = Serial.read();
command[4] = '\0';
Serial.println(command);
if (strcmp(command, "AAAA") == 0) {
digitalWrite(LED, HIGH);
Serial.println("LED13 is ON");
} else if (strcmp(command, "BBBB") == 0) {
digitalWrite(LED, LOW);
Serial.println("LED13 is OFF");
}
}
}
I have that code, that reads 4 characters long strings. However, I need it to ignore any string that is not 4 characters long.
So, imagine this input:
AAAA
BBBB
BBB
AAAA
Right now, it reads {"AAAA", "BBBB", "BBBA"}.
I need it to read {"AAAA", "BBBB", "AAAA"}.
Any idea? Thank you.
You can check the duration time of inter-character delay. Set a timeout, such as 100ms. When there is no more data received after the specified timeout, that means the whole string is transferred completely. Then you can check the length of the string and execute your application logic.