I am working on a system that rings a bell when someone decides to ring it or it is timed. This also includes emergency bells, such as when there is an earthquake threat or an armed intruder. On the armed intruder bell it rings for .5 seconds (500ms) and then waits 1.5s (1500ms) and repeats. However, on the fourth cycle the bell gets stuck on and will stay on until I turn the arduino off. I have tried many ways of trying to fix it but it will not work. I will post my code below and could someone have a look and see what is wrong with it?
Thank you!
Java for loop:
for(int i = 0; i < 21; i++) {
out.write("500".getBytes("UTF-8"));
out.flush();
Thread.sleep(2000);
}
Arduino Code:
int Relay = 13;
//The pin that the relay is attached to
//int time;
//Creates temp variable
void setup() {
Serial.begin(9600);
pinMode(Relay, OUTPUT);
}
void loop() {
while(true) {
//Check if data has been sent from the computer:
if (Serial.available()) {
int time;
//Assign serial value to temp
time = Serial.parseInt();
//Output value to relay
delay(1000);
digitalWrite(Relay, HIGH);
delay(time);
digitalWrite(Relay, LOW);
}
}
}
You might try putting a small delay into the if-loop, after checking and before reading from the Serial (just a few ms. Maybe put your 1000ms delay at the beginning). As the data arrive serialized, and you check with a high frequency, it might be, that the program starts reading out data before everything is received.
I don't know how exactly Serial.parseInt() works, but maybe try:
out.write("500\n".getBytes("UTF-8"));
in your Java-loop
Related
I've been working in a project where I need to manipulate each instrument in a MIDI file in java.
Then I decided to get each MIDI Event from each track from the Sequence and send it to a Receiver. After that the thread waits the time each tick lasts then do it again with the next tick.
The problem is: the sound of the instruments gets very messed, as well as their order.
I tried to execute each track alone too, but it's still messed!
The code:
Sequence sequence = MidiSystem.getSequence(new File(source));
Synthesizer synth = MidiSystem.getSynthesizer();
//Gets a MidiMessage and send it to Synthesizer
Receiver rcv = synth.getReceiver();
//Contains all tracks and events from MIDI file
Track[] tracks = sequence.getTracks();
synth.open();
//If there are tracks
if(tracks != null)
{
//Verify the division type of the sequence (PPQ, SMPT)
if(sequence.getDivisionType() == Sequence.PPQ)
{
int ppq = sequence.getResolution();
//Do the math to get the time (in miliseconds) each tick takes
long tickTime = TicksToMiliseconds(BPM,ppq);
//Returns the number of ticks from the longest track
int longestTrackTicks = LongestTrackTicks(tracks);
//Each iteration sends a new message to 'receiver'
for(int tick = 0; tick < maiorTick ; tick++)
{
//Iteration of each track
for(int trackNumber = 0; trackNumber < tracks.length; trackNumber++)
{
//If the number of ticks from a track isn't already finished
//continue
if(tick < tracks[trackNumber].size())
{
MidiEvent ev = tracks[trackNumber].get(tick);
rcv.send(ev.getMessage(),-1);
}
}
Thread.sleep(tickTime);
}
}
}
synth.close();
As ntabee said, Track.get(n) returns the nth event in the track; to get events by time, you have to compare the events' times manually.
Furthermore, Thread.sleep() is not very precise and can wait for a longer time than desired.
These errors will add up.
To change MIDI messages in real time, tell the sequencer to play to your own Receiver, then do whatever you want to the events and pass them on to the 'real' Receiver.
At least, your code looks like ringing on/off something at every tickTime msec. period.
track.get(tick) just returns the tick-th event in the track, not the event(s) at the moment of tick.
If your goal is just playing a sound, Java provides a high level API for it, see e.g. http://www.jsresources.org/examples/midi_playback_and_recording.html
I decided to use the sequencer. I didn't know, but the "start" method runs in a new thread and while it's still running I can mute each instrument I want to, and that is exactly what I wanted.
Thanks for the answers!
I have a ping))) sensor (HC - SR04) which is connected correctly.
I start it up without being connected to ground (otherwise it doesn't even want to start) and it keeps writing 0 to the serial window (distance). Once I plug it in the ground pin, I get a few lines of correct distance readings and than it stops and hangs, no more results in the serial window, and the board itself seems to be in a fault state, and I need to unplug it from the USB, disconnect the ground, and then re-plug to the USB.
What can be the cause of the problem?
Code:
#define echoPin 2 // Echo Pin
#define trigPin 4 // Trigger Pin
#define LEDPin 13 // Onboard LED
int maximumRange = 200; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance
int currentDistance = 0;
void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
}
void loop() {
/* The following trigPin/echoPin cycle is used to determine the
distance of the nearest object by bouncing soundwaves off of it. */
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
//Calculate the distance (in cm) based on the speed of sound.
distance = duration/58.2;
if (distance >= maximumRange || distance <= minimumRange){
/* Send a negative number to computer and Turn LED ON
to indicate "out of range" */
Serial.println("-1");
digitalWrite(LEDPin, HIGH);
} else {
/* Send the distance to the computer using Serial protocol, and
turn LED OFF to indicate successful reading. */
Serial.println(distance);
digitalWrite(LEDPin, LOW);
}
//Delay of 50 ms before next reading.
delay(50);
}
------------------------ UPDATE ------------------------------
It would seem that the problem is not with the sensor, but with the serial interface: I have attached an LED to the board and am giving it an analog value according to the distance. Once the Arduino gets "stuck", the LED keeps working correctly, so I guess the problem is with the Arduino shutting down the serial interface and stopping data transmission through the USB.
How can this problem be fixed?
The solution to the sensor being stuck at zero is in this link. It's the 2nd post, by docdoc. You will need to use the NewPing library which is far better.
A working code:
#include <NewPing.h>
#define TRIGGER_PIN 12
#define ECHO_PIN 11
#define MAX_DISTANCE 200
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
void setup() {
Serial.begin(9600);
}
void loop() {
delay(50);
unsigned int uS = sonar.ping();
pinMode(ECHO_PIN,OUTPUT);
digitalWrite(ECHO_PIN,LOW);
pinMode(ECHO_PIN,INPUT);
Serial.print("Ping: ");
Serial.print(uS / US_ROUNDTRIP_CM);
Serial.println("cm");
}
Link: http://forum.arduino.cc/index.php?topic=55119.15
NewPing link: http://playground.arduino.cc/Code/NewPing
From what you say, it looks like there is an interminent shortcut between the ground and the device... Or maybe there's a faulty component shortcuting to the ground. So my advice would be:
Is the Arduino working correctly?
Test whether the Arduino itself works flawlessly without having the sensor connected (upload a echo sketch),
Is the sensor device working correctly?
Test continuity of all soldering points (look up for a shortcut bridge between the ground and a signal),
Test with another sensor device (if you happen to have a spare) to see if the problem persists
Or try the same device with another Arduino.
About your code itself, which is not, as far as I can tell, the source of your problems, I'd advice you to change the declaration of your global constants to either:
const uint8_t maximumRange = 200; // Maximum range needed
const uint8_t minimumRange = 0; // Minimum range needed
const uint8_t currentDistance = 0;
Or use the preprocessor:
#define maximumRange 200 // Maximum range needed
#define minimumRange 0 // Minimum range needed
#define currentDistance = 0
And move:
long duration, distance; // Duration used to calculate distance
inside your loop() function. Avoiding non-constant globals as much as possible is always a good idea (though not always possible with Arduino objects).
I was able to find the cause of the problem. It seems that the Arduino's serial monitor was causing the "crash", because while using a server utility that allows the Arduino output to be used in Flash (serproxy) the Arduino performs consistently and without problems.
A video of the project is Arduino + Ping))) Sensor - Change display in application according to distance.
I need to progam an Arduino for a project, and I thought I'd add something fancy, a LED color changing thingy. The LED has a sort of cyclus in which it changes colors, which takes about 40 seconds to do so. Though, the bat sensor, that makes the LED burn, registers the whole time and tells the LED a couple of times a second to go on, again. The LED never gets the time to change color and only stays the first color.
I have no idea how to fix this. I was trying to give the LED a delay or something, but apparently I did that wrong. The code so far is this;
//Pin which triggers ultrasonic sound.
const int pingPin = 13;
//Pin which delivers time to receive echo using pulseIn().
int inPin = 12;
//Range in cm which is considered safe to enter, anything
//coming within less than 5 cm triggers the red LED.
int safeZone = 10;
//LED pin numbers
int redLed = 3, greenLed = 5;
void setup() {
//Initialize serial communication
Serial.begin(9600);
//Initializing the pin states
pinMode(pingPin, OUTPUT);
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
}
void loop()
{
//Raw duration in milliseconds, cm is the
//converted amount into a distance.
long duration, cm;
//Sending the signal, starting with LOW for a clean signal 2 staat voor reactie.
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
//Setting up the input pin, and receiving the duration in
//microseconds for the sound to bounce off the object in front.
pinMode(inPin, INPUT);
duration = pulseIn(inPin, HIGH); //Documentation for pulseIn():
//http://www.arduino.cc/en/Reference/PulseIn
//Convert the time into a distance
cm = microsecondsToCentimeters(duration);
//Printing the current readings to the serial display
Serial.print(cm);
Serial.print("cm");
Serial.println();
//If het is groter dan 10 dan gaat het lichtje uit
//else het is binnen bepaalde cm dan gaat het aan van 0 naar 255.
if(cm>10)
{
analogWrite(redLed, 0);
}
else{
analogWrite(redLed, map(cm,0,10,255,0));
dela
}
if(cm>5)
{
analogWrite(greenLed, 0);
}
else{
analogWrite(greenLed, map(cm,0,5,255,0));
}
delay(100);
}
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
But it still needs some kind of delay thing I think. I'm not sure what the sensor I'm using is called but it has two rounds with sensors in them, one sends and one receives, it measures how long it takes to receive back the sound and in my code I translate that to cm.
I hope you can help and understand what my problem is since my knowledge of this language is very poor.
Set a timeout value for pulseIn. Otherwise the program gets stuck in the line duration = pulseIn(inPin, HIGH); as you don't get the chance to send out another ultrasonic pulse if the previous ultrasonic pulse did not result in an echo.
In this case, the maximum range is 10 cm (20 cm travel distance for the sound pulse) so the timeout value can be set accordingly (s is distance, v is velocity and t is time):
s = v * t => t = s / v = 2 * 0.1 m / 343.2 m/s = 582.8 µs
The speed of sound is assumed to be in dry air at 20 °C.
Allowing for the width of the outgoing pulse of 2 µs the total time would then be 584.8 µs.
Instead of
duration = pulseIn(inPin, HIGH);
use
duration = pulseIn(inPin, HIGH, 585);
Other notes:
The outgoing pulse is very short, intended to be 2 µs.
digitalWrite() is quite slow, on the order of 5 µs so the actual pulse may be longer than 2 µs. Even so, the ultrasonic transducer may not be able to start up in such a short time.
Even if the outgoing pulse is longer than you think it is, it is on the order of a single period (if the ultrasonic transducer operates at 100 kHz the period is 10 µs)
Try to experiment with longer ranges and longer outgoing pulses to be sure this is not the problem.
Use delay(ms) to delay for 40 ms as required. That will shut the Arduino for 40 ms before it gets to process any data from the ultrasonic sensor.
My code is here from which I get result either true or false that weather it ping to the host I mention in it or not,
try
{
InetAddress address = InetAddress.getByName("192.168.1.125");
boolean reachable=address.isReachable(10000));
out.print(PingHost.DrawTable());
out.print("Is host reachable? " + reachable);
}
catch(Exception e)
{
out.print(e.printStackTrace());
}
I want to count the no of times it try to ping the host if it is not ping success fully fro the first time and the max no of count for ping would be 10
Hopes for your suggestions
Thanks in Advance
final static int MAX_PINGS = 10;
final static int TIMEOUT= 10000;
int countFailed = 0;
for (int i=0; i<MAX_PINGS; i++){
if (address.isReachable(TIMEOUT)){
System.out.println("Pinged successfully");
break;
}else{
countFailed++;
}
}
Note: giving 10000ms (10 seconds) as timeout is too much. I suggest it should be around 1000 ms.
Assuming that address.isReachable(10000)) is doing the ping, and returns true or false, then you want something like this:
int counter = 0;
do
{
counter ++;
if(address.isReachable(10000))
{
break;
}
}
while (counter < 10)
// now counter contains the number of attempts
I think you'd do well to find a good book on programming, to come up with a solution similar to this should not be something you need to ask about.
I would first question why this code needs to reside in a JSP. A request to this JSP will take forever to get back to you if the host is unreachable. Any solution that uses a member variable to track the count will also be problematic since it will run into concurrency issues.
You are better off writing LaceySnr's code on a servlet and spawning that code on a separate thread.
I want to check an huge amount (thousands) of Websites, if they are still running. Because I want to get rid of unececarry entries in my HostFile Wikipage about Hostfiles.
I want to do it in a 2 Stage process.
Check if something is running on Port 80
Check the HTTP response code (if it's not 200 I have to check the site)
I want to multithread, because if I want to check thousands of addresses, I cant wait for timeouts.
This question is just about Step one.
I have the problem, that ~1/4 of my connect attempts don't work. If I retry the not working ones about ~3/4 work? Do I not close the Sockets correctly? Do I run into a limit of open Sockets?
Default I run 16 threads, but I have the same problems with 8 or 4.
Is there something I'm missing
I have simplified the code a little.
Here is the code of the Thread
public class SocketThread extends Thread{
int tn;
int n;
String[] s;
private ArrayList<String> good;
private ArrayList<String> bad;
public SocketThread(int tn, int n, String[] s) {
this.tn = tn;
this.n = n;
this.s = s;
good = new ArrayList<String>();
bad = new ArrayList<String>();
}
#Override
public void run() {
int answer;
for (int i = tn * (s.length / n); i < ((tn + 1) * (s.length / n)) - 1; i++) {
answer = checkPort80(s[i]);
if (answer == 1) {
good.add(s[i]);
} else {
bad.add(s[i]);
}
System.out.println(s[i] + " | " + answer);
}
}
}
And here is the checkPort80 Method
public static int checkPort80(String host)
Socket socket = null;
int reachable = -1;
try {
//One way of doing it
//socket = new Socket(host, 80);
//socket.close();
//Another way I've tried
socket = new Socket();
InetSocketAddress ina = new InetSocketAddress(host, 80);
socket.connect(ina, 30000);
socket.close();
return reachable = 1;
} catch (Exception e) {
} finally {
if (socket != null) {
if (socket.isBound()) {
try {
socket.close();
return reachable;
} catch (Exception e) {
e.getMessage();
return reachable;
}
}
}
}
}
About Threads, I make a ArrayList of Threads, create them and .start() them and right afterwards I .join() them, get the "God" and the "Bad" save them to files.
Help is appreciated.
PS: I rename the Hosts-file first so that it doesn't affect the process, so this is not an issue.
Edit:
Thanks to Marcelo Hernández Rishr I discovered, that HttpURLConnection seems to be the better solution. It works faster and I can also get the HttpResponseCode, which I was also interested anyways (just thought it would be much slower, then just checking Port 80). I still after a while suddenly get Errors, I guess this has to do with the DNS server thinking this is a DOS-Attack ^^ (but I should examine futher if the error lies somewhere else) also fyi I use OpenDNS, so maybe they just don't like me ^^.
x4u suggested adding a sleep() to the Threads, which seems to make things a little better, but will it help me raise entries/second i don't know.
Still, I can't (by far) get to the speed I wanted (10+ entries/second), even 6 entries per second doesn't seem to work.
Here are a few scenarios I tested (until now all without any sleep()).
number of time i get first round how many entries where entries/second
threads of errors processed until then
10 1 minute 17 seconds ~770 entries 10
8 3 minute 55 seconds ~2000 entries 8,51
6 6 minute 30 seconds ~2270 entries 5,82
I will try to find a sweet spot with Threads and sleep (or maybe simply pause all for one minute if I get many errors).
Problem is, there are Hostfiles with one million entries, which at one entry per second would take 11 Days, which I guess all understand, is not expectable.
Are there ways to switch DNS-Servers on the fly?
Any other suggestions?
Should I post the new questions as separate questions?
Thanks for the help until now.
I'll post new results in about a week.
I have 3 suggestions that may help you in your task.
Maybe you can use the class HttpURLConnection
Use a maximum of 10 threads because you are still limited by cpu, bandwidth, etc.
The lists good and bad shouldn't be part of your thread class, maybe they can be static members of the class were you have your main method and do static synchronized methods to add members to both lists from any thread.
Sockets usually try to shut down gracefully and wait for a response from the destination port. While they are waiting they are still blocking resources which can make successive connection attempts fail if they were executed while there have still been too many open sockets.
To avoid this you can turn off the lingering before you connect the socket:
socket.setSoLinger(false, 0);