I'm trying to make an alarm with my arduino, which always activates at 0:00 and deactivates at 23:59 so the variables reset and its easier to make. Right now I want to make, that the buzzer starts after 1 minute. But the maths don't really work or I'm missing something.
Code:
/* Tutorial:
* ---------
* -Set the custom Variables
* -Plug arduino at exact 0:00
*
*
*/
//Imports
//Custom Variables
int alarmMin = 1;
//Other Variables
boolean active = false;
int alarmMilli = alarmMin * 60000;
//Pins
int pBuzzer = 2;
//Start
void setup() {
Serial.begin(9600);
Serial.println("-------------------------------");
Serial.println(alarmMin);
Serial.println(alarmMilli);
}
//Loop
void loop() {
Serial.println(active);
Serial.println(millis()/1000);
Serial.println(alarmMilli/1000);
Serial.println("-----");
//If alarm-time started
if(millis()/1000 == alarmMilli/1000){
active = true;
}
//Buzzer
if(active){
digitalWrite(2, HIGH);
}
}
Output:
-------------------------------
1
-5536
0
0
-5
-----
0
0
-5
-----
0
0
-5
-----
0
0
-5
-----
...
Why is 1*6000 = -5536
The int type on an Arduino Uno is a 16-bit integer, i.e. it's range its range is from -32,768 to 327,67. Thus, 60,000 is already outside the range resulting in seemingly strange math.
Instead of int, use long. Its range is from -2,147,483,648 to 2,147,483,647.
Related
My servo only starts to "change" (that is what the code tells me anyway) when it is set for 180 degrees.
I've tried searching the website as well as Google, but this seems to be something that has to do very specifically with writing to Servo in an advanced non-repeatable kind of way.
The code that changes the servo is:
#include <SoftwareSerial.h>
#include <Servo.h>
const int rxPin = 12;
const int txPin = 13;
SoftwareSerial bluetooth (rxPin, txPin);
Servo myServo;
boolean canMove = true;
int rotation = 0;
int currentRotation = 0;
void setup() {
Serial.begin(9600); // Begins Serial communication
bluetooth.begin(9600);
myServo.attach(11); // Sets a servo on pin 11
}
void loop() {
// put your main code here, to run repeatedly:
// Checks if Serial has something to read
if (bluetooth.available() > 0) {
rotation = bluetooth.read(); // Reads it and sets it to an integer
}
currentRotation = myServo.read();
if (currentRotation != rotation) {
Serial.println("Current Rotation:");
Serial.println(currentRotation);
Serial.println("Set to:");
Serial.println(rotation);
for (int i = currentRotation; i < rotation; i++) {
Serial.println("Writing to servo");
myServo.write(i);
}
}
}
There is a Processing program that sends the data to the Arduino, but I can perfectly see that the numbers are coming in in the Arduino's Serial Monitor (they vary from 0 to 180)
After doing this the only thing that shows up in the Serial Monitor is:
Current Rotation:
93
Set to:
0
Current Rotation:
93
Set to:
0
Current Rotation:
93
Set to:
0
Current Rotation:
93
Set to:
0
Current Rotation:
93
Set to:
0
over and over. The servo just twitches back and forth. The only time it changes (the number to set to comes from the Processing program) is when the number it is set to be 180. Then it moves even more back and forth and says:
Current Rotation:
179
Set to:
180
Writing to servo
Current Rotation:
179
Set to:
180
Writing to servo
over and over. What is going on and how can I fix it? Cheers, and thanks for the help!
There are some problems with your code:
You don't need to read current servo value, just save the last gave value.
Moving a servo step by step is not a good option as it may have some error for movement. You need to find a dynamic delay based on a threshold of movement. For example, suppose that your max delay time for the servo to fully move from 0 to 180 is 2 seconds, so if you need to move the servo for 90 degrees you need 1 second delay.
You just need to move your servo when a new data came so set servo when new data comes.
Remember to set max_delay based on your servo.
#include <SoftwareSerial.h>
#include <Servo.h>
const int rxPin = 12;
const int txPin = 13;
SoftwareSerial bluetooth(rxPin, txPin);
Servo myServo;
boolean canMove = true;
int rotation = 0;
int currentRotation = 0;
// how much time takes servo to move
int move_delay = 0;
// maximum time for changing servo state from lowest to highest value
const int max_delay = 2;
void setup()
{
Serial.begin(9600); // Begins Serial communication
bluetooth.begin(9600);
myServo.attach(11); // Sets a servo on pin 11
}
void loop()
{
// put your main code here, to run repeatedly:
// Checks if Serial has something to read
if (bluetooth.available() > 0)
{
rotation = bluetooth.read(); // Reads it and sets it to an integer
Serial.print("New value: ");
Serial.println(rotation);
Serial.print("Current Rotation: ");
Serial.println(rotation);
if (currentRotation != rotation)
{
Serial.println("Setting new value");
// find a proper delay
move_delay = (max_delay / 180) * (abs(rotation - currentRotation)) * 1000;
myServo.write(rotation);
delay(move_delay);
currentRotation = rotation;
}
}
}
I've been doing a project on reading doppler speed and creating velocity data. I don't have a firm background on electric engineering / signal processing but I've researched quite a bit so far. Please bear with me if I get things wrong in my explanation.
I am currently using HB100 and CDM324 breakout model. The objective in this project is to get the voltage reading from the module and create a spectrogram though FFT in MATLAB. I got a sample data from BlackCatScience with the hand moving towards the Sensor at a fast speed. Its plot is shown below:
Hand Speed Using Doppler Radar
And I've assembled my arduino kit like the picture below:
Arduino-HB100_kit
Connections are:
VCC -> 5V GND -> GND FOUT -> Pin 8 VOUT -> Pin A5
So far, I found out that HB100 supports pulse/CW usage and used the code below to measure the frequency using HB100.
#include <MsTimer2.h>
#include <FreqMeasure.h>
//--------------GlOBAL VARIALBES---------------------
double raw_data = FreqMeasure.read();
double sum = 0;
int count = 0;
double raw_data_array[10];
unsigned long timeStamp = 0;
//---------------------------------------------------
void setup() {
Serial.begin(115200);
FreqMeasure.begin();
Serial.print("Time (ms)");
Serial.print("\t");
Serial.println("Hz");
}
void loop() {
timer();
freq_measure();
}
void timer() {
timeStamp+=1;
}
void freq_measure() {
while (timeStamp < 101) {
if(FreqMeasure.available()) {
//average readings
sum += FreqMeasure.read();
count ++;
if (count > 2) {
float frequency = FreqMeasure.countToFrequency(sum/count);
// Serial.print(timeStamp);
// Serial.print("\t");
Serial.println(frequency);
timeStamp++;
sum = 0;
count = 0;
}
}
}
}
The problem with this code is that, I want to measure the voltage reading at every, say for example, 1 millisec. However, this code is similar to using pulseIn function and the rate at which the data is out differs on whether I'm moving my hand to/from the sensor or not. When I'm not moving, the data output become slow, and when I'm moving, the data output rate is fast.
Hence, I decided to use some other code and use analogRead function like below:
//-----------------------------------------------------------------
#define RADAR A5 //pin number for VOUT
//--------------------GLOBAL VARIABLES-----------------------------
unsigned long timeStamp;
//-----------------------------------------------------------------
void setup() {
Serial.begin(115200);
pinMode(RADAR, INPUT);
Serial.println(F("Settings Complete" ));
}
void loop() {
// 1 millisec == 0.001 second --> 1000 millisec == 1 second
// we want about 5 seconds of data, hence the loop runs for 5000 millisec
while (timeStamp < 5000){
showReading();
}
}
void showReading() {
// timeStamp = millis();
// Serial.print(timeStamp);
// Serial.print("\t");
//Read input on analog pin 5:
int sensorData = analogRead(RADAR);
// float voltage = sensorData * (5.0 / 1023.0);
Serial.println(sensorData);
}
This time, the serial monitor is giving me a value between 0 and 1023 and that's great, but even if I move my hand in front of the sensor, the values change but minimally. What should I do to correct this and get a plot like the graph above?
Thanks for reading such a long question. Have a great day!
I'm writing a simple program on my ATTINY 85. The program is supposed to light the LED pin when chip is awake, and turn it off when it is asleep.
However, when I set watchdog timer to reset after 0.5 s, it does so on first reset, and then resets after only ~100ms.
I checked it using an oscilloscope, prinstcreen is under this link:
https://i.snag.gy/WovBsf.jpg
Here is the code:
/*
* Sketch for testing sleep mode with wake up on WDT.
* Donal Morrissey - 2011.
* ATTINY85
*/
#include <TinyWireM.h> // I2C Master lib for ATTinys which use USI - comment this out to use with standard arduinos
#include <LiquidCrystal_attiny.h> // for LCD w/ GPIO MODIFIED for the ATtiny85
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
//uwaga na numer pinu! nie używać tego z resetem
#define OUT_PIN 3
#define GPIO_ADDR 0x27
LiquidCrystal_I2C lcd(GPIO_ADDR, 16, 2); // set address & 16 chars / 2 lines
volatile int f_wdt=1;
/***************************************************
* Name: ISR(WDT_vect)
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Watchdog Interrupt Service. This
* is executed when watchdog timed out.
*
***************************************************/
ISR(WDT_vect){
if(f_wdt == 0){
f_wdt=1;
}
else{
// lcd.clear();
// lcd.print("WDT overrun");
// delay(500);
}
}
/***************************************************
* Name: enterSleep
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Enters the arduino into sleep mode.
*
***************************************************/
void enterSleep(void)
{
// lcd.clear();
// lcd.print("Asleep...");
set_sleep_mode( SLEEP_MODE_PWR_DOWN ); /* EDIT: could also use SLEEP_MODE_PWR_DOWN for lowest power consumption. */
sleep_enable();
/* Now enter sleep mode. */
sleep_mode();
/* The program will continue from here after the WDT timeout*/
sleep_disable(); /* First thing to do is disable sleep. */
/* Re-enable the peripherals. */
power_all_enable();
}
/***************************************************
* Name: setup
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Setup for the serial comms and the
* Watch dog timeout.
*
***************************************************/
void setup()
{
/* Setup the LCD */
lcd.init(); // initialize the lcd
lcd.backlight(); // Print a message to the LCD.
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Initializing...");
delay(500);
/*** Setup the WDT ***/
/* Clear the reset flag of watchdog interrupts, so that they are available again. */
MCUSR &= ~(1<<WDRF);
/* Enable configuration changes
*/
WDTCR |= (1<<WDCE) | (1<<WDE);
/*
WDP3 WDP2 WDP1 WDP0 Number of WDT Typical Time-out at
Oscillator Cycles VCC = 5.0V
0 0 0 0 2K (2048) cycles 16 ms
0 0 0 1 4K (4096) cycles 32 ms
0 0 1 0 8K (8192) cycles 64 ms
0 0 1 1 16K (16384) cycles 0.125 s
0 1 0 0 32K (32768) cycles 0.25 s
0 1 0 1 64K (65536) cycles 0.5 s
0 1 1 0 128K (131072) cycles 1.0 s
0 1 1 1 256K (262144) cycles 2.0 s
1 0 0 0 512K (524288) cycles 4.0 s
1 0 0 1 1024K (1048576) cycles 8.0 s
*/
/* set new watchdog timeout prescaler value */
WDTCR = 0<<WDP3 | 1<<WDP2 | 0<<WDP1 | 1<<WDP0 ;
/* Enable the WD interrupt (note no reset). */
WDTCR |= (1<<WDIE);
lcd.clear();
lcd.print("Initialisation complete.");
delay(100);
}
/***************************************************
* Name: enterSleep
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Main application loop.
*
***************************************************/
void loop()
{
if(f_wdt == 1)
{
// lcd.clear();
// lcd.print("Awake!");
digitalWrite( OUT_PIN, HIGH );
delay(1000);
/* Don't forget to clear the flag. */
f_wdt = 0;
digitalWrite( OUT_PIN, LOW );
/* Re-enter sleep mode. */
enterSleep();
}
else
{
/* Do nothing. */
}
}
Anyone got idea on how to fix this issue?
EDIT:
Alright, I managed to fix it. The only thing that I had to change is to enable WDT interrupt right before going to sleep, and then disable it after sleep. So the enetSleep function looks like this:
void enterSleep(void)
{
lcd.clear();
lcd.print("Asleep...");
/* Enable the WD interrupt (note no reset). */
WDTCR |= (1<<WDIE);
set_sleep_mode( SLEEP_MODE_PWR_DOWN ); /* EDIT: could also use SLEEP_MODE_PWR_DOWN for lowest power consumption. */
sleep_enable();
/* Now enter sleep mode. */
sleep_mode();
/* The program will continue from here after the WDT timeout*/
sleep_disable(); /* First thing to do is disable sleep. */
/* Re-enable the peripherals. */
power_all_enable();
/* Disable the WD interrupt */
WDTCR &= ~_BV(WDIE);
}
And, of course, I deleted
WDTCR |= (1<<WDIE);
line from setup.
I posted a little while ago on here and you were really helpful. And i've managed to adapt some code to get it working on an lcd display.
What I would like some extra help with is firstly is there a way of defining the one_time_max etc different depending on the high low state of a pin. This way i could use a switch to change the times so it could switch between NTSC and PAL.
Secondly would anyone be kind enough to explain what is happening in the middle part of this code. I understand that there is a volatile boolean which can be true of false. But later in the code you make an IF statement against it and I don't fully understand how that works. Any help would be appreciated.
Here is a picture of how it's going so far. I'll keep you guys up to date as the project continues :)
// Code from forum post Dec 12, 2007
//
//
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#define one_time_max 600 // these values are setup for PA video
#define one_time_min 400 // It's the durstion of a one and zero with a little bit of room for error.
#define zero_time_max 1050 //
#define zero_time_min 950 //
#define icpPin 8 // ICP input pin on arduino
//#define one_time_max 475 // these values are setup for NTSC video
//#define one_time_min 300 // PAL would be around 1000 for 0 and 500 for 1
//#define zero_time_max 875 // 80bits times 29.97 frames per sec
//#define zero_time_min 700 // equals 833 (divide by 8 clock pulses)
#define end_data_position 63
#define end_sync_position 77
#define end_smpte_position 80
volatile unsigned int pin = 13;
volatile unsigned int bit_time; // volatile instructs the variable to be stored in RAM
volatile boolean valid_tc_word; // booleon can be either of two values true or false
volatile boolean ones_bit_count; // booleon can be either of two values true or false
volatile boolean tc_sync; // booleon can be either of two values true or false
volatile boolean write_tc_out; // booleon can be either of two values true or false
volatile boolean drop_frame_flag; // booleon can be either of two values true or false
volatile byte total_bits; //this stores a an 8-bit unsigned number
volatile byte current_bit; //this stores a an 8-bit unsigned number
volatile byte sync_count; //this stores a an 8-bit unsigned number
volatile byte tc[8]; //this stores a an 8-bit unsigned number
volatile char timeCode[11]; //this stores a an 8-bit unsigned number
/* ICR interrupt vector */
ISR(TIMER1_CAPT_vect) //ISR=Interrupt Service Routine, and timer1 capture event
{
//toggleCaptureEdge
TCCR1B ^= _BV(ICES1); //toggles the edge that triggers the handler so that the duration of both high and low pulses is measured.
bit_time = ICR1; //this is the value the timer generates
//resetTimer1
TCNT1 = 0;
if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // this gets rid of anything that's not what we're looking for
{
total_bits = 0;
}
else
{
if (ones_bit_count == true) // only count the second ones pluse
ones_bit_count = false;
else
{
if (bit_time > zero_time_min)
{
current_bit = 0;
sync_count = 0;
}
else //if (bit_time < one_time_max)
{
ones_bit_count = true;
current_bit = 1;
sync_count++;
if (sync_count == 12) // part of the last two bytes of a timecode word
{
sync_count = 0;
tc_sync = true;
total_bits = end_sync_position;
}
}
if (total_bits <= end_data_position) // timecode runs least to most so we need
{ // to shift things around
tc[0] = tc[0] >> 1;
for(int n=1;n<8;n++) //creates tc[1-8]
{
if(tc[n] & 1)
tc[n-1] |= 0x80;
tc[n] = tc[n] >> 1;
}
if(current_bit == 1)
tc[7] |= 0x80;
}
total_bits++;
}
if (total_bits == end_smpte_position) // we have the 80th bit
{
total_bits = 0;
if (tc_sync)
{
tc_sync = false;
valid_tc_word = true;
}
}
if (valid_tc_word)
{
valid_tc_word = false;
timeCode[10] = (tc[0]&0x0F)+0x30; // frames this converst from binary to decimal giving us the last digit
timeCode[9] = (tc[1]&0x03)+0x30; // 10's of frames this converst from binary to decimal giving us the first digit
timeCode[8] = ':';
timeCode[7] = (tc[2]&0x0F)+0x30; // seconds
timeCode[6] = (tc[3]&0x07)+0x30; // 10's of seconds
timeCode[5] = ':';
timeCode[4] = (tc[4]&0x0F)+0x30; // minutes
timeCode[3] = (tc[5]&0x07)+0x30; // 10's of minutes
timeCode[2] = ':';
timeCode[1] = (tc[6]&0x0F)+0x30; // hours
timeCode[0] = (tc[7]&0x03)+0x30; // 10's of hours
drop_frame_flag = bit_is_set(tc[1], 2); //detects whether theree is the drop frame bit.
write_tc_out = true;
}
}
}
void setup()
{
lcd.begin (16, 2);
pinMode(icpPin, INPUT); // ICP pin (digital pin 8 on arduino) as input
bit_time = 0;
valid_tc_word = false;
ones_bit_count = false;
tc_sync = false;
write_tc_out = false;
drop_frame_flag = false;
total_bits = 0;
current_bit = 0;
sync_count = 0;
lcd.print("Finished setup");
delay (1000);
TCCR1A = B00000000; // clear all
TCCR1B = B11000010; // ICNC1 noise reduction + ICES1 start on rising edge + CS11 divide by 8
TCCR1C = B00000000; // clear all
TIMSK1 = B00100000; // ICIE1 enable the icp
TCNT1 = 0; // clear timer1
}
void loop()
{
if (write_tc_out)
{
write_tc_out = false;
if (drop_frame_flag)
lcd.print("TC-[df] ");
else
lcd.print("TC-NO DROP FRAME");
lcd.setCursor(0, 1);
lcd.print((char*)timeCode);
lcd.print("\r");
lcd.setCursor(11, 1);
lcd.print("......");
delay (40);
lcd.clear(); } }
an if removed from the type declaration should not affect the «volatile» keyword as shown in the code ▬ compiler-writers have a trade-off where folks want to do systems ( stuff like here ) and it jams the machine so they tell you volatileis some sort of exotic thing but is far from that when used here
it is the way it should be here ~ that is not a business machine
For our moving-mirror project we use 6 Ultrasonic Sensors to rotate a servo motor where the Mirror is resting on.
Our concept is if 1 sensor detects someone/something infront of them the mirror turns away from that person. Although I can't seem to have it turn away.
I have used the library "NewPing", which can be seen at https://code.google.com/p/arduino-new-ping/ and I used the 15 sensor example (https://code.google.com/p/arduino-new-ping/wiki/15_Sensors_Example)
Is the correct way of coding this or should I start from scratch and use another method?
Thanks in advance!
The Code:
// ---------------------------------------------------------------------------
// This example code was used to successfully communicate with 15 ultrasonic sensors. You can adjust
// the number of sensors in your project by changing SONAR_NUM and the number of NewPing objects in the
// "sonar" array. You also need to change the pins for each sensor for the NewPing objects. Each sensor
// is pinged at 33ms intervals. So, one cycle of all sensors takes 495ms (33 * 15 = 495ms). The results
// are sent to the "oneSensorCycle" function which currently just displays the distance data. Your project
// would normally process the sensor results in this function (for example, decide if a robot needs to
// turn and call the turn function). Keep in mind this example is event-driven. Your complete sketch needs
// to be written so there's no "delay" commands and the loop() cycles at faster than a 33ms rate. If other
// processes take longer than 33ms, you'll need to increase PING_INTERVAL so it doesn't get behind.
// ---------------------------------------------------------------------------
// Sketch of 6 sensors with servo
// ---------------------------------------------------------------------------
// | \ | | / |
// | ----------- ----------- ----------- ----------- |
// | |Sensor 2 | |Sensor 3 | |Sensor 4 | |Sensor 5 | |
// | \ ----------- ----------- ----------- ----------- |
// | \ / |
// | ----------- ----------- |
// | |Sensor 1 | |Sensor 6 | |
// | ----------- ----------- ----------- |
// | | Servo | |
// | ----------- |
// | |
// | if Sensor 1 measures someone close the Servo should turn away from |
// | Sensor 1 |
// ---------------------------------------------------------------------------
#include <NewPing.h>
#include <Servo.h>
Servo myservo;
#define SONAR_NUM 6 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.
int val; // The number which makes the Servomotor rotate
NewPing sonar[SONAR_NUM] = { // Sensor object array.
NewPing(1, 2, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
NewPing(3, 4, MAX_DISTANCE),
NewPing(5, 6, MAX_DISTANCE),
NewPing(7, 8, MAX_DISTANCE),
NewPing(9, 10, MAX_DISTANCE),
NewPing(11, 12, MAX_DISTANCE)
};
void setup() {
Serial.begin(115200);
pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.
for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}
void loop() {
for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
currentSensor = i; // Sensor being accessed.
cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
}
}
// -------------- BEGIN SELFMADE CODE -----------------------
if(cm[1] <= 30) {
val = 60;
}
if(cm[2] <= 30) {
val = 100;
}
if(cm[3] <= 30) {
val = 140;
}
if(cm[4] <= 30) {
val = 120;
}
if(cm[5] <= 30) {
val = 80;
}
if(cm[6] <= 30) {
val = 40;
}
myservo.write(val);
// -------------- END SELFMADE CODE --------------------
}
void echoCheck() { // If ping received, set the sensor distance to array.
if (sonar[currentSensor].check_timer())
cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
for (uint8_t i = 0; i < SONAR_NUM; i++) {
Serial.print(i);
Serial.print("=");
Serial.print(cm[i]);
Serial.print("cm ");
}
Serial.println();
}
This is how I would structure the code.
I just moved the self made part into a the oneSensorCycle(). I dont really like the way it uses globes, but it still looks pretty clean.
#include <NewPing.h>
#include <Servo.h>
Servo myservo;
#define SONAR_NUM 6 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.
//int val; // The number which makes the Servomotor rotate
NewPing sonar[SONAR_NUM] = { // Sensor object array.
NewPing(1, 2, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
NewPing(3, 4, MAX_DISTANCE),
NewPing(5, 6, MAX_DISTANCE),
NewPing(7, 8, MAX_DISTANCE),
NewPing(9, 10, MAX_DISTANCE),
NewPing(11, 12, MAX_DISTANCE)
};
void setup() {
Serial.begin(115200);
pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.
for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}
void loop() {
for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
currentSensor = i; // Sensor being accessed.
cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
}
}
}
void echoCheck() { // If ping received, set the sensor distance to array.
if (sonar[currentSensor].check_timer())
cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
int val =0;
for (uint8_t i = 0; i < SONAR_NUM; i++) {
Serial.print(i);
Serial.print("=");
Serial.print(cm[i]);
Serial.print("cm ");
// -------------- BEGIN SELFMADE CODE -----------------------
if(cm[0] <= 30) {
val = 60;
}
if(cm[1] <= 30) {
val = 100;
}
if(cm[2] <= 30) {
val = 140;
}
if(cm[3] <= 30) {
val = 120;
}
if(cm[4] <= 30) {
val = 80;
}
if(cm[5] <= 30) {
val = 40;
}
myservo.write(val);
// -------------- END SELFMADE CODE -----------------------
}
Serial.println();
}