I'm pretty sure there is a stupid error here but I'm afraid I can't for the life of me work it out!
Simple test program that gets the error:
#include <Servo.h>
Servo myservo;
int testPIN = 13;
int inputPIN = 5;
void setup()
{
myservo.attach(8);
pinMode(testPIN, OUTPUT);
pinMode(inputPIN, INPUT);
}
void loop()
{
if (digitalRead(inputPIN) == HIGH)
{
digitalWrite(testPIN, HIGH);
myservo.write(90);
}
else
{
digitalWrite(testPIN, LOW);
myservo.write(0);
}
}
The arduino sweep example (http://arduino.cc/en/Tutorial/Sweep) works, so I'm fairly confident the electronics works.
The testPIN also goes on and off as expected so the if statement is working as expected.
Any ideas/suggestions welcome!
EDIT - Sorry the error is that the servo doesn't move at all
EDIT 2 - Something a bit odd is going on here. If I copy/paste the sweep loop into the if clause, the servo reacts as expected (ie input = high makes the servo run a sweep loop, which it doesn't break out of until it reaches the end of, as expected). My immediate thought was delays were needed, but they seem to make no difference no matter how long they are or where they are added in the if/else clauses.
I don't know which arduino board you have, but on the arduino uno, i'm pretty sure that the pin 8 is not a PWM output. And you can not run a servo on a non-PWM output.
See this image of the Uno board, and notice that there is no tilde (the indication that a port supports PWM) on pin 8:
Have you tried using SoftwareServo.h instead? This example looks like what you are trying to accomplish: http://playground.arduino.cc/ComponentLib/servo
The sweep program that you're linking to is using pin 9, which is a PWM on an uno. Your code is using pin 8, which is NOT a PWM output. Switch your servo over to pin 9 and change the attach in your code to pin 9 and, assuming that this is your only issue, your code should work.
As suggested in the comments, I've just written a function that moves the servo slowly. Not an elegant solution but servo response time isn't issue so it does the trick.
Thanks for all the help and suggestions, and to #praks411 for the wrapper function work around.
Related
I am using analogWrite() in my code. Everything works fine when I am not using the servo library. In other words, everything is fine when I disable this line //servo_9.attach(9); If I enable this line, the PWM will be wrong and weird. Any idea why the Tinkercad simulator is acting weird?
#include <Servo.h>
int led =9;
Servo servo_9;
void setup() {
servo_9.attach(9);
Serial.begin(9600);
}
void loop() {
for(int n=0;n<255;n++){
analogWrite(led,n);
delay(5);
}
}
This video shows what is happening:
click here
The documentation for the servo library clearly states.
On boards other than the Mega, use of the library disables
analogWrite() (PWM) functionality on pins 9 and 10, whether or not
there is a Servo on those pins.
I only want to print simple text but it print unilimited weird character and never stop, (when I remove Serial.print() it continues to print weird characters).
This is the weird text that loop
-*⸮ql⸮7⸮$⸮
*!8P⸮⸮⸮V⸮)3 ⸮;⸮ 1⸮zY⸮b⸮ڔ!⸮⸮$q⸮,*⸮ı⸮N
⸮a!u⸮ 1⸮zY⸮b⸮⸮⸮⸮⸮⸮!⸮ 1⸮zY⸮W(⸮⸮⸮xI⸮
,*-⸮l⸮N
⸮a!u⸮,*⸮⸮⸮nbb⸮H⸮⸮⸮⸮,*⸮⸮⸮nbb⸮H$⸮
1⸮zY⸮b⸮ڔ!X⸮⸮⸮⸮,*⸮⸮⸮nbb⸮H$⸮
*!8Pt⸮
My code :
void setup() {
}
void loop() {
}
I hope you can help me, thanks :)
UPDATE
I completely removed Serial.begin(9600) and Serial.print() and I still have the problem O_o
If you are using arduino IDE ( you probably are ) you can try changing the baud rates. That's what happened to me in arduino some time ago
I just changed the Flash memory speed to 40MHz instead of 80MHz
You need to make sure that the baud rate in the code and baud rate of the serial monitor are the same.
Example:
if your code has : Serial.begin(115200);
then change the baud rate of serial monitor to 115200, this can be done by accessing the baud as shown in the pictureimage below
My end goal is to try and send some simple data that's stored on my Raspberry pi 3 to an external server/website using a sim800c from a c++ program. I believe the easiest way to do this is to issue "AT commands" to the sim/modem however I'm struggling to do this. I can't figure out how I'm actually suppose to issue AT commands or how I can check if they're working. For testing purposes I've written some code which should send a text message to a phone number once I've gotten this working it should be fairly straight forward to figure out the AT commands to communicate with a server.
Below is an image of how I've wired everything up which I'm fairly confident is correct.
https://i.imgur.com/zysmNXE.jpg
Below is the basic c++ code that I've written using various guides, it compiles and runs in terminal however I don't get any response from the AT commands and more importantly as far as I can tell their not actually being executed. I've tried changing the fake number to my personal one but it didn't make a difference.
#include <stdio.h>
#include <string.h>
#include <wiringPi.h>
#include <wiringSerial.h>
int main ()
{
int connection;
printf("Opening connection \n");
connection = serialOpen("/dev/ttyAMA0", 9600);
delay(1000);
printf("Connection: %d\n", connection);
printf("\n");
//Set gsm to text mode
serialPuts(connection,"AT+CMGF \r\n");
delay(1000);
//Number that the message should be sent to
serialPuts(connection,"AT+CMGS=\"12345678900\"\r\n");
delay(1000);
//The message
serialPuts(connection,"Hello World");
delay(1000);
//Print ctrl+x
serialPuts(connection,"\x1A");
delay(1000);
printf("Done \n");
return 0 ;
}
As far as I can tell there are 3 likely reasons why it's not working;
A possible config/settings issue with the pi
I've wired it up incorrectly
The sim/module isn't working
I'm just not sure how to go about testing/finding what is causing the issue. If I could get my code to output the response of the AT commands after doing "serialPuts" that might help me figure out whats going on but I haven't made much luck doing that. Alternatively If anyone has an idea why the commands don't appear to be working or can provide me some ways to debug/test them that would be great.
The issue turned out just to be a simple wiring mistake.
I had wired the txd pin of the sim module to the txd pin on the raspberry pie as I was under the impression you just needed to match the pins however I didn't think/realize that the txd pin needed to go to the rxd pin instead. Changing these around allowed me to see the commands & responses being returned from the module.
To actually get the gprs working I also needed to temporarily set the pwr pin to low then high.
I'm trying to get the basics done with my Arduino, and thus I'm starting off small.
That said, I want the Arduino to listen for simple, multiple commands being sent from my Raspberry Pi (I'm emulating this through the serial monitor now, however)
This is the code I'm working with:
#include "SoftwareSerial.h"
void setup()
{
Serial.begin(9600);
delay(100);
}
void loop() {
if (Serial.find("test1")) {
delay(100);
Serial.println("TEST1 command received");
}
if (Serial.find("test2")) {
delay(100);
Serial.println("TEST2 command received");
}
}
}
Sadly, only the test1 command triggers a serial print response, test2 no. Can anyone here help point me in the right direction?
Thank you!
From reading the documentation, I don't think you can use the find() function like that.
Consider what happens if test2 is input, when the find("test1") call is running. It will probably consume all characters up to and including the 2, and then return false, at which point those characters are lost.
I think you should design an actual protocol, with some delimiter between commands, and read/parse those.
I'm working on an Arduino sketch where I created two traffic lights, one for normal traffic and one for pedestrians. I created a function for each of these two lights, which loops it through it's cycle (for example: turn yellow, wait 20 seconds, then turn red and wait again). These are called aTrafficlight() and pTrafficlight, where a is the normal light and p the one for the pedestrians. In my loop() function I set a digitalRead for a button. When this button is pressed the traffic lights should cycle through their loops one at a time (so the normal light turns red, pTrafficlight waits a bit, then turns green, blinks a few times, turns red, waits and ends the loop, so it goes to it's original state.)
This all works. But now I want to add a buzzer. This buzzer must beep once a second while the pTrafficlight is red, once a tenth second while it's green and twice per two seconds while it's flashing green.
Here I encountered a few problems:
- When waiting in original state (button's not pressed) it seems I can sometimes press the button without reaction because the loop is still going. I need to figure out how to avoid waiting in the loop when buttonState == LOW. (There's a function wait(int sec))
- When the button is pressed, it loops through the cycles. I could just write some kind of loop implementing the traffic light being red and beeping at the same time, but I'd rather keep these seperated.
- Same for the double beeps. I do not want the beeping and flashing of the light to be in the same for loop, as it's confusing and difficult to read and understand the code.
Here's my loop():
int buttonState = 0;
void loop(){
buttonState = digitalRead(pButton);
if(buttonState == LOW){
vSet("red");
pSet("green");
// This is where I tried to create the sound.
digitalWrite(pSound, HIGH);
delay(10);
digitalWrite(pSound, LOW);
wait(1);
} else {
aTrafficlight();
pTrafficlight();
}
}
Is there a way to solve my problems with multithreading? I tried to look it up at arduino.cc and google, but I can't find a way I understand enough to use it in my existing code.
If not, do you have any better suggestions?
You don't need multi-threading. You need to use timers, whether via interrupts (as Pawel wrote) or via another mechanism, such as the Metro library, that lets the code continue to loop through while the timer is running. See this question and answer: How Can I Create Interrupts in C for Arduino
Coincidentally, I recently posted some material both on state machines and the Arduino, as Hans Passant mentioned, and on alternatives to delay(), both with additional references you might find useful.
You could use a time-slice design. Let me just outline this in very general terms.
First code loop so that it always issues a delay(1) and set a mod 10 counter as:
int stopWhen = -1; // at startup
// etc.
x = (x+1)%10; // every time loop execs
Then when buttonState == LOW
if (stopwWhen = -1)
{
stopWhen = x;
// beep etc.
}
But on every loop:
// always exec this:
if (stopWhen == x)
{
stopWhen = -1;
// stop beeping.
}