My goal is to test individual servos for a project I'm doing.
Which may have faulty servos or bad wiring,
though the program I created for testing simply asks and returns an integer from input, then attaches a servo to it. But fails to return the correct value.
Code:
#include <Servo.h>
Servo s;
int pin;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("Enter Pin");
}
void loop() {
// Getting Input
while (Serial.available() == 0) {}
pin = Serial.parseInt();
Serial.println(pin); // returns value given. <-- this is where it breaks and always returns "0".
//attaching servo
s.attach(pin);
// Testing Servo
s.write(90);
delay(1000);
s.write(0);
}
Your code works fine but it reads '\n' (EOL) character and parses it to 0.
Calling parseInt with SKIP_ALL and ignore '\n' helps to solve the issue:
pin = Serial.parseInt(SKIP_ALL, '\n');
Related
I've been trying to create an oscilloscope for serial data from my Arduino. In the Arduino serial plotter I can get a good waveform up to suitable frequencies, but when I try send the data to Processing it doesn't receive all the data from the Arduino. Is there a way around this?
Arduino
const int analogIn = A6;
int integratorOutput = 0;
void setup() {
// put your setup code here, to run once:
pinMode(3, OUTPUT);
pinMode(2, OUTPUT);
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
integratorOutput = analogRead(analogIn);
Serial.println(integratorOutput);
}
Processing
void serialEvent (Serial port) {
// get the ASCII string:
String inString = port.readStringUntil('\n');
if (inString != null) {
inString = trim(inString); // trim off whitespaces.
inByte = float(inString); // convert to a number.
inByte = map(inByte, 0, 1023, 100, height-100); //map to the screen height.
println(inByte);
newData = true;
}
}
Thanks!
It's because readStringUntil is a non blocking function. Let's assume Arduino is printing a line: 12345\n The serial port at 115200 bits per seconds is relatively slow, so it's possible that the at some point the receiving buffer contains only a part of the message, for example: 1234. When the port.readStringUntil('\n') is executed it doesn't encounter a \n in the buffer so it fails and returns a NULL. You can solve this problem by using bufferUntil as in this example
i am trying to save IP address and password in NODE MCU EEPROM. Here is the code snippet.
The problem is the first time i am reading, i am getting garbage values because there were no values set earlier, so how do i determine if there were values set earlier so that i can place default values.
#include <Arduino.h>
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
const char* ssid_default = "NodeMCU";
const char* pass_default = "1234";
uint addr = 0;
ESP8266WebServer server(80);
struct
{
int was_set = 9090; // already Set = 9090, other numbers = not set
char ssid_default[40] = "NODEMCU";
char pass_default[40] = "1234";
int step = 0;
/* data */
}creds;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
EEPROM.begin(512);
delay(5000);
EEPROM.get(addr, creds);
Serial.print("Default SSID: ");
Serial.println(String(creds.ssid_default));
Serial.print("Default Pass:");
Serial.println(String(creds.pass_default));
Serial.print("Times Executed: ");
Serial.println(String(creds.step));
creds.step = creds.step + 1;
EEPROM.put(addr, creds);
Serial.println("Times Executed Incremented, Re-plug Devise to see changes");
EEPROM.commit();
}
void loop() {
delay(1000);
// put your main code here, to run repeatedly:
}
You already have a magic element in your struct that you could check for its special value after reading the EEPROM.
/*...*/
EEPROM.get(addr, creds);
if (creds.was_set != 9090) {
/* set default values */
}
/*...*/
Most application implement a checksum to not only check for unset data, but also for changed data. The algorithm depends on your needs, but don't invent something new, use well-known ones like CRC.
Edit:
Depending on the size of your magic number or checksum, there will always be a small probability that a random set of bits will be recognized as correct/initialized. With a 32-bit value this probability can never be smaller than 2^(-32), which is about 1 in 4 billions.
A checksum has the advantage over a magic value that all values are taken into account.
There is no such thing like 100% safety.
currently, I am working on a project to read char inputs from serial monitor and command Arduino to switch on/off specific pins. The problem I am facing is, I am unable to read the complete char array entered in the serial monitor. can anyone tell me what am I doing wrong?
#define X 13 //led pin
char txt[15];
int i;
int Status=0;
void setup() { // put your setup code here, to run once:
pinMode(X,OUTPUT);// setting the pin flow of control as output
Serial.begin(9600);
while(!Serial)
{
; //to wait for pc to connect
}
Serial.println("\nHome Automation");
dashprint();
}
void loop() { // put your main code here, to run repeatedly:
if(Serial.available()>0)
{ i=0;
while(Serial.available()>0) //if serial available
{ char inchar=Serial.read();
txt[i]=inchar; // add char to txt string
i++;// increment to where to write next
txt[i]='\0'; //null termination
}
Serial.print(txt);
check();
}
}
void dashprint() //to print dashes
{
Serial.println("-----------------------------------------------");
Serial.println("give me some command"); //ask for command
}
void check()
{ if(strncmp(txt,"ON",2)==0)
{
digitalWrite(X,HIGH);
Status=1;
}
else if(strncmp(txt,"OFF",3)==0)
{ digitalWrite(X,LOW);
Status=0;
}
else if(txt=="STATUS")
{
}
else Serial.println("ERROR");
}
output:
Home Automation
give me some command
OERROR
NERROR
ERROR
expected output:
Home Automation
give me some command
ON
Your arduino is too fast to read the text "ON" in one round.
9600 is 1 ms per character.
A simple workaround is, to add a little delay
if(Serial.available()>0) {
delay(3); // wait for the whole message
i=0;
while(Serial.available()>0) {
...
ADD:
Additionally, you obviously receive a '\n' (newline) character. Make sure it's not causing troubles.
And increase the delay or have a better approach in general, if you expect more than 3 characters ( "STATUS" )
struct MYObject {char a[256];};
//structure works well with EEPROM put and get functions.
//also lets to input large strings, more then 64 bytes, as http
void setup() {
MYObject str ={" "};
Serial.begin(115200);
while (!Serial.available()) delay (10); //wait for string
int i = 0;
int k= Serial.available();
while (k > 0){
char inchar = Serial.read(); //read one by one character
str.a[i] = inchar;
i++;
if (k < 3) delay (10); //it gives possibility to collect more characters on stream
k = Serial.available();
}
str.a[i]='\0'; //null terminator
//now lets see result
Serial.println(str.a);
//.....
}
I have a problem with my brand new Arduino, it seems that
no matter what I print with
Serial.println()
be it numbers, strings or anything else, I get garbage
on the Arduino serial monitor:
Not even the simplest hello world program works.
Could you help me identify the problem and solve it?
I found the solution :)
I wrote a test program and found a working baud-rate at 600.
My test program:
long baudrates[] = {600,1200,2400,4800,9600,14400,19200,28800,38400,56000,57600,115200,128000,256000};
unsigned char baudcounter = 0;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication
Serial.begin(baudrates[baudcounter]);
}
// the loop routine runs over and over again forever:
void loop() {
Serial.println();
Serial.println(baudrates[baudcounter]);
Serial.println(" !\"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
Serial.println();
baudcounter++;
baudcounter %= sizeof(baudrates)/sizeof(long);
delay(1000); // delay
Serial.begin(baudrates[baudcounter]); // switch baudrate
}
I have and arduino sketch that needs to do several operations on a timed schedule using the TimeAlarms.h library. However, one of the operations, reading a hall sensor via interrupts, seems to interact poorly with the TimeAlarms library.
I'm using the TimeAlarms library from here: http://www.pjrc.com/teensy/td_libs_TimeAlarms.html
And have adapted the hall sensor script from here:
http://www.seeedstudio.com/wiki/G3/4_Water_Flow_sensor
I can run the hall sensor code on it own fine. However, when I try to run the hall sensor code along with Alarm.timerRepeat it hangs after entering the check_flow function.
Running the code below outputs only enter CF and then hangs. The same occurs if you try the check_flow_alarm_delay function instead, which uses the TimeAlarm version of Delay.
However, if you comment out Alarm.timerRepeat(10, showseconds); in setup
and Alarm.delay(0); in loop the hall sensor works fine.
Strangely, if you comment out sei(); and cli(); in the check_flow function the script works fine, and seems to count properly with the hall sensor. Why would this work? And should I be concerned that I'm not actively setting the time between sei() and cli(), leading to reliability issues in the sensor?
Note: you should be able to run the code without actually having a hall sensor, the output will just be 0 L/hr.
// reading liquid flow rate using Seeeduino and Water Flow Sensor from Seeedstudio.com
// Code adapted by Charles Gantt from PC Fan RPM code written by Crenn #thebestcasescenario.com
// http:/themakersworkbench.com http://thebestcasescenario.com http://seeedstudio.com
#include <Time.h>
#include <TimeAlarms.h>
#include <Wire.h>
volatile int NbTopsFan; //measuring the rising edges of the signal
int Calc;
int hallsensor = 2; //The pin location of the sensor
void rpm () //This is the function that the interupt calls
{
NbTopsFan++; //This function measures the rising and falling edge of the hall effect sensors signal
}
void setup() //
{
Serial.begin(9600); //This is the setup function where the serial port is initialised,
pinMode(hallsensor, INPUT); //initializes digital pin 2 as an input
attachInterrupt(0, rpm, RISING); //and the interrupt is attached
Alarm.timerRepeat(10, showseconds);
}
void loop ()
{
// Serial.println( second() );
// stalls at enter CF
// check_flow();
// stalls at enter CF
check_flow_alarm_delay();
Alarm.delay(0);
}
void showseconds ()
{
Serial.println( second() );
}
void check_flow ()
{
Serial.println("enter CF");
int Calc;
NbTopsFan = 0; //Set NbTops to 0 ready for calculations
// sei(); //Enables interrupts
delay(1000); //Wait 1 second
// cli(); //Disable interrupts
Calc = (NbTopsFan * 60 / 5.5); //(Pulse frequency x 60) / 5.5Q, = flow rate in L/hour
Serial.print (Calc, DEC); //Prints the number calculated above
Serial.print (" L/hour\r\n"); //Prints "L/hour" and returns a new line
}
void check_flow_alarm_delay ()
{
Serial.println("enter CFAD");
int Calc;
NbTopsFan = 0; //Set NbTops to 0 ready for calculations
// sei(); //Enables interrupts
Alarm.delay(1000); //Wait 1 second
// cli(); //Disable interrupts
Calc = (NbTopsFan * 60 / 5.5); //(Pulse frequency x 60) / 5.5Q, = flow rate in L/hour
Serial.print (Calc, DEC); //Prints the number calculated above
Serial.print (" L/hour\r\n"); //Prints "L/hour" and returns a new line
}
delay() uses interrupts. Disabling them interferes with the function.