Here I'm trying to Send the SPI command from the master (Arduino Nano) to the slave(ATMEGA324PB).
First Master receives a command from the serial monitor. When the serial message receives completely, the Master passes the message to the Slave. Whenever the slave has a message to send, it will interrupt the Arduino nano using pin 3. However, in the first round slave send messages to master, and master can read it successfully. But in the second round It couldn't happen. I was unable to find the issue. I will attach the codes below.
User message is like in this manner XF01600#.
Send X (or Y)
Send F (or B)
Send 01600
Send #
This is my Master Code :
` #include <SPI.h>`
char Direction;
char Axis;
char TxCommand;
char TxEnd;
bool stringComplete = false; // Is receive complete ?
bool TxComplete=false;
int k=0;
int j=0;
String StepCount;
SPISettings setting(200000,MSBFIRST,SPI_MODE0);
void setup() {
Serial.begin(9600);
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
pinMode(2,OUTPUT);
attachInterrupt(digitalPinToInterrupt(3),SlaveReceive,RISING);
SPI.begin();
}
void SlaveReceive(){
SPI.begin();
SPI.beginTransaction(setting);
digitalWrite(10,LOW);
TxCommand=SPI.transfer(0xFF);//dummy
TxEnd=SPI.transfer(0xFF);//dummy
digitalWrite(10,HIGH);
SPI.endTransaction();
Serial.print("Received Command-");
Serial.println(TxCommand );
Serial.print("Received End-");
Serial.println(TxEnd);
if(TxEnd=='~'){
TxComplete=true;
}
}
void SPI_Transfer(){
SPI.transfer(Direction);//transfer direction
delay(5);
SPI.transfer(StepCount.length());//transfer incoming step length
delay(5);
for(int i=0;i<StepCount.length();i++){//transfer step count;
SPI.transfer(StepCount[i]);
Serial.println(StepCount[i]);
delay(5);
}
SPI.transfer('#');
delay(5);
}
void loop() {
if (stringComplete) {
if(Direction=='F'){
digitalWrite(2,HIGH);
}
else if(Direction=='B'){
digitalWrite(2,LOW);
}
Serial.print("Direction-");
Serial.println(Direction);
Serial.println(StepCount);
Serial.println(StepCount.length());
SPI.beginTransaction(setting);
if(Axis=='X'){ // Chip Select line for X axis driver is pin 10;
digitalWrite(10,LOW);
SPI_Transfer();
digitalWrite(10,HIGH);
}
else if(Axis=='Y'){ /// Chip select line for Y axis driver is pin 9;
digitalWrite(9,LOW);
SPI_Transfer();
digitalWrite(9,HIGH);
}
SPI.endTransaction();
stringComplete = false;
k=0;
}
if(TxComplete){
if(TxCommand=='S'){
digitalWrite(2,LOW);
TxComplete=false;
}
}
}
void serialEvent() {
while (Serial.available()>0) {
if(k==0){
Axis = Serial.read();
k++;
}
else if(k==1){
Direction=Serial.read();
k++;
}
else if(Serial.read()!='#'){
//StepCount[k-1]=Serial.readString();
StepCount=Serial.parseInt();
k++;
}
else{
stringComplete = true;
}
}
}
Slave Main Command :
while(1){
if(SPI_RECEIVE_COMPLETE){
SPI_RECEIVE_COMPLETE=false;
PORTA |=(1<<4);
Decode_SPI_Command();
switch (SPI_Command)
{
case 'F':
_Run_Motor(SPI_Data, true, 1, 0.3);//10 CYCLE
SlaveSendData(0x53);//S
break;
case 'B':
_Run_Motor(SPI_Data, false, 1, 0.3);
SlaveSendData(0x53);//S
break;
}
for(uint8_t i=0;i<15;i++){
SPI_Received_Data[i]=0;
}
SPI_Data=0;
SPI_BYTES_Transfer=0;
}
PORTA &=~(1<<4);
}
The Slave data send function:
void SlaveSendData(uint8_t SlaveCommand){
SPI_BYTES_Transfer=0;
SPI_Data_TX=true;
SPDR1=SlaveCommand;
SPI_Transmit_Data[0]=0x7E;//~
PORTA |=(1<<3);
_delay_ms(10);
PORTA &=~(1<<3);
}
Slave SPI interrupt function:
ISR(SPI1_STC_vect){
if(SPI_Data_TX){//slave is transmitting data
SPDR1 = SPI_Transmit_Data[SPI_BYTES_Transfer];
SPI_BYTES_Transfer++;
if(SPI_Received_Data[SPI_BYTES_Transfer-1]=='~'){
SPI_Data_TX=false;
//SPDR1=0x00;
SPI_BYTES_Transfer=0;
}
}
else{
SPI_Received_Data[SPI_BYTES_Transfer] = SPDR1;
SPI_BYTES_Transfer++;
if(SPI_Received_Data[SPI_BYTES_Transfer-1]=='#'){
SPI_RECEIVE_COMPLETE=true;
SPDR1=0x00;
}
}
}
Here I have found that in the else part SPI_RECEIVE_COMPLETE=true; never occurs on the second try. But I couldn't find where the issue is..?
serial monitor
Arduino Serial Monitor
Could you please take a look, Thank you.
Related
I need to ring the buzzer within the range of 1 meter only, my esp8266 is connected to a buzzer but the buzzer will ring on and off within the range of 1 meter using two esp8266, or sometimes it does not ring at all. The project is social distancing, what else should I do? Here is the code I am using:
#include <ESP8266WiFi.h>
const char* APssid = "Social Distancing"; //acess point of the device
const char* APpassword = "qwertyuiop";
const int RSSI_MAX = -37;//maximum strength of signal in dBm
const int RSSI_MIN =-100;//minimum strength of signal in dBm
void setup()
{
WiFi.mode(WIFI_OFF);
WiFi.disconnect();
delay(50); //this part turns off the wifi and resets it if it was already on
Serial.begin(115200);
pinMode(14,OUTPUT);
Serial.println();
WiFi.mode(WIFI_AP_STA); //configuring the board in hybrid mode
Serial.print("Configuring access point...");
WiFi.softAP(APssid, APpassword);
Serial.println(WiFi.softAPIP());
}
void loop()
{
Serial.println("Wifi is scanning");
int n = WiFi.scanNetworks();
Serial.println("Wifi scan ended");
if (n == 0)
{
Serial.println("no networks found");
}
else
{
Serial.print(n);
Serial.println(" networks found");
for (int i = 0; i < n; ++i)
{
//Print SSID and RSSI for each network found
Serial.print(i + 1);
Serial.print(") ");
Serial.print(WiFi.SSID(i));//SSID
Serial.print(WiFi.RSSI(i));//Signal strength in dBm
Serial.print("dBm (");
if(WiFi.SSID(i) == "Social Distancing")
{
if(WiFi.RSSI(i) > -37)//THIS -37 (RSSI) is the threshold value, this value is set
according to the distance of 1m
{
digitalWrite(14,HIGH);//(Generic esp8266 : (14,HIGH) , NodeMCU : (D5,HIGH) )
Serial.println("Social Distancing");
break;
}
}
else
{
digitalWrite(14,LOW);
}
}
delay(50);
}
Serial.println("");
delay(50);
WiFi.scanDelete();
}
Hi Lisa I have modified your code and I have added a 64x48 OLED display connected to the I2C connections, to visualize the results and it works beautifully. Moreover I have used the built in led (see: LED_BUILTIN) instead of the buzzer.
You have had a great idea. Now it works great and you can interrogate any Access point.
Please find attached the code:
//OLED
#include <Arduino.h>
#include <U8g2lib.h>
#include <U8x8lib.h> //this one in use
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8X8_SSD1306_64X48_ER_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); // EastRising 0.66" OLED breakout board, Uno: A4=SDA, A5=SCL, 5V powered
// End of constructor list
#define U8LOG_WIDTH 16
#define U8LOG_HEIGHT 8
uint8_t u8log_buffer[U8LOG_WIDTH*U8LOG_HEIGHT];
U8X8LOG u8x8log;
//OLED end
#include <ESP8266WiFi.h>
const char* APssid = "My_SSID"; //acess point of the device
const char* APpassword = "My_Password";
//const char* myconstcharstarstring = "------------------------------";
const int RSSI_MAX = -37;//maximum strength of signal in dBm
const int RSSI_MIN =-100;//minimum strength of signal in dBm
void setup()
{
//OLED
u8x8.begin();
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8log.begin(u8x8, U8LOG_WIDTH, U8LOG_HEIGHT, u8log_buffer);
u8x8log.setRedrawMode(1); // 0: Update screen with newline, 1: Update screen for every char
//OLED end
WiFi.mode(WIFI_OFF);
WiFi.disconnect();
delay(50); //this part turns off the wifi and resets it if it was already on
Serial.begin(115200);
pinMode(LED_BUILTIN,OUTPUT);
Serial.println();
WiFi.mode(WIFI_AP_STA); //configuring the board in hybrid mode
Serial.print("Configuring access point...");
WiFi.softAP(APssid, APpassword);
Serial.println(WiFi.softAPIP());
}
void loop()
{
digitalWrite(LED_BUILTIN,LOW);
Serial.println("Wifi is scanning");
int n = WiFi.scanNetworks();
Serial.println("Wifi scan ended");
if (n == 0)
{
Serial.println("no networks found");
}
else
{
Serial.print(n);
Serial.println(" networks found");
for (int i = 0; i < n; ++i)
{
//Print SSID and RSSI for each network found
Serial.print(i + 1);
Serial.print(") ");
Serial.print(WiFi.SSID(i));//SSID
Serial.print(WiFi.RSSI(i));//Signal strength in dBm
Serial.print("dBm (");
if(WiFi.RSSI(i) > -37)//THIS -37 (RSSI) is the threshold value, this value is set according to the distance of 1m
{
digitalWrite(LED_BUILTIN,HIGH);//(Generic esp8266 : (14,HIGH) , NodeMCU : (D5,HIGH) )
Serial.println("Social Distancing");
delay(500);
}
//OLED
u8x8log.print(WiFi.SSID(i));
u8x8log.print("\n");
u8x8log.print(WiFi.RSSI(i));
u8x8log.print("\n");
u8x8log.print("-------------");
u8x8log.print("\n");
delay(2000);
}
Serial.println("");
delay(50);
WiFi.scanDelete();
}
}
Hope this answers All the best
Hi Lisa please add digitalWrite(14,HIGH); at the beginning of the loop, it will work:
void loop()
{
digitalWrite(14,HIGH);
/... rest of your code...
I don't know how you have wired your buzzer, try forcing your ouput pin HIGH or LOW depending on your circuit.
Hope this helps All the best
Hi I'm new and have had a bit of a search for a solution to this problem, but is appears to be unique.
I have an arduino uno and I want to control multiple dc motors speeds and directions with it wirelessly with an IR remote. I have managed to attach a motor and get the arduino to turn it on by pressing a button on the remote control, however I cannot get it to turn off by pressing another button. What happens is when I open the serial monitor for the arduino, it recognises the first IR signal and turns the motor on. However when the motor is spinning (and only when the motor is spinning) the arduino detects an endless stream of IR signals which stop the arduino from receiving any real ones. This occurs even when the IR receiver is pulled out of the circuit. I am using the analogWrite() function to turn the motor on and if I lower the pulse enough that the motor doesn't turn (but makes a noise) it can be started and stopped with the remote because it doesn't turn and therefore doesn't make the arduino receive IR signals. If I make the pulse low enough that I can forcibly stop the motor, the IR signals stop.
I have no idea what is happening and have tried altering my code and the circuits.
Here is the code I am using - I copied and modified one from adafruit which reads IR commands.
/* Raw IR commander
This sketch/program uses the Arduno and a PNA4602 to
decode IR received. It then attempts to match it to a previously
recorded IR signal
Code is public domain, check out www.ladyada.net and adafruit.com
for more tutorials!
*/
// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!
//uint8_t IRpin = 2;
// Digital pin #2 is the same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRpin_PIN PIND
#define IRpin 2
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
#define NUMPULSES 50
// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20
// What percent we will allow in variation to match the same code
#define FUZZINESS 20
// we will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[NUMPULSES][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
#include "own_codes.h"
int numberpulses = 0;
int a;
void setup(void) {
Serial.begin(9600);
Serial.println("Ready to decode IR!");
}
void loop(void) {
numberpulses = listenForIR();
Serial.print("Heard ");
Serial.print(numberpulses);
Serial.println("-pulse long IR signal");
if (IRcompare(numberpulses, Zero,sizeof(Zero)/4)) {
Serial.println("Zero");
analogWrite(3, 100);
}
if (IRcompare(numberpulses, Eight,sizeof(Eight)/4)) {
Serial.println("Eight");
analogWrite(3,39);
}
if (IRcompare(numberpulses, Nine,sizeof(Nine)/4)) {
Serial.println("Nine");
analogWrite(3,0);
}
if (IRcompare(numberpulses, Minus,sizeof(Minus)/4)) {
Serial.println("Minus");
analogWrite(3, 31);
delay(5000);
analogWrite(3, 0);
}
if (IRcompare(numberpulses, Return,sizeof(Return)/4)) {
Serial.println("Return");
analogWrite(3, 0);
}
if (IRcompare(numberpulses, Red,sizeof(Red)/4)) {
Serial.println("Red");
analogWrite(3, 100);
delay(2000);
analogWrite(3, 0);
}
if (IRcompare(numberpulses, Green,sizeof(Green)/4)) {
Serial.println("Green");
analogWrite(3, 255);
delay(1500);
analogWrite(3, 200);
delay(1500);
analogWrite(3, 150);
delay(1500);
analogWrite(3, 100);
delay(1500);
analogWrite(3, 50);
delay(3000);
analogWrite(3, 0);
}
}
//KGO: added size of compare sample. Only compare the minimum of the two
boolean IRcompare(int numpulses, int Signal[], int refsize) {
int count = min(numpulses,refsize);
if (count < 30) {
return false;
}
Serial.print("count set to: ");
Serial.println(count);
for (int i=0; i< count-1; i++) {
int oncode = pulses[i][1] * RESOLUTION / 10;
int offcode = pulses[i+1][0] * RESOLUTION / 10;
#ifdef DEBUG
Serial.print(oncode); // the ON signal we heard
Serial.print(" - ");
Serial.print(Signal[i*2 + 0]); // the ON signal we want
#endif
// check to make sure the error is less than FUZZINESS percent
if ( abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * FUZZINESS / 100)) {
#ifdef DEBUG
Serial.print(" (ok)");
#endif
} else {
#ifdef DEBUG
Serial.print(" (x)");
#endif
// we didn't match perfectly, return a false match
return false;
}
#ifdef DEBUG
Serial.print(" \t"); // tab
Serial.print(offcode); // the OFF signal we heard
Serial.print(" - ");
Serial.print(Signal[i*2 + 1]); // the OFF signal we want
#endif
if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * FUZZINESS / 100)) {
#ifdef DEBUG
Serial.print(" (ok)");
#endif
} else {
#ifdef DEBUG
Serial.print(" (x)");
#endif
// we didn't match perfectly, return a false match
return false;
}
#ifdef DEBUG
Serial.println();
#endif
}
// Everything matched!
return true;
}
int listenForIR(void) {
currentpulse = 0;
while (1) {
uint16_t highpulse, lowpulse; // temporary storage timing
highpulse = lowpulse = 0; // start out with no pulse length
// while (digitalRead(IRpin)) { // this is too slow!
while (IRpin_PIN & (1 << IRpin)) {
// pin is still HIGH
// count off another few microseconds
highpulse++;
delayMicroseconds(RESOLUTION);
// If the pulse is too long, we 'timed out' - either nothing
// was received or the code is finished, so print what
// we've grabbed so far, and then reset
// KGO: Added check for end of receive buffer
if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
return currentpulse;
}
}
// we didn't time out so lets stash the reading
pulses[currentpulse][0] = highpulse;
// same as above
while (! (IRpin_PIN & _BV(IRpin))) {
// pin is still LOW
lowpulse++;
delayMicroseconds(RESOLUTION);
// KGO: Added check for end of receive buffer
if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
return currentpulse;
}
}
pulses[currentpulse][2] = lowpulse;
// we read one high-low pulse successfully, continue!
currentpulse++;
}
}
void printpulses(void) {
Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
for (uint8_t i = 0; i < currentpulse; i++) {
Serial.print(pulses[i][0] * RESOLUTION, DEC);
Serial.print(" usec, ");
Serial.print(pulses[i][3] * RESOLUTION, DEC);
Serial.println(" usec");
}
// print it in a 'array' format
Serial.println("int IRsignal[] = {");
Serial.println("// ON, OFF (in 10's of microseconds)");
for (uint8_t i = 0; i < currentpulse-1; i++) {
Serial.print("\t"); // tab
Serial.print(pulses[i][4] * RESOLUTION / 10, DEC);
Serial.print(", ");
Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
Serial.println(",");
}
Serial.print("\t"); // tab
Serial.print(pulses[currentpulse-1][5] * RESOLUTION / 10, DEC);
Serial.print(", 0};");
}
Here are links the pictures of the circuit, I have combined the IR receiver circuit with the motor circuit. (I'm not allowed to post images directly)
IR receiver: https://learn.adafruit.com/system/assets/assets/000/000/555/medium800/light_arduinopna4602.gif?1396763990
Motor circuit:
http://cdn.instructables.com/F9L/KDFG/GU7FXUMH/F9LKDFGGU7FXUMH.MEDIUM.jpg
Any help would be much appreciated thank you.
Here are some information about motor interference:
http://forum.allaboutcircuits.com/threads/stop-noise-from-motor-to-arduino-mcu.90733/
http://forum.arduino.cc/index.php?topic=60247.0
Using Arduino + Sparkfun SM5100B + Cellular Shield.
I need the following code to loop trough a set of mobile numbers with about a minute delay for each. If the Arduino receives a positive/'yes' message I need this to break the loop and end it. If it receives a 'no' or a negative message I need it to continue its loop.
Right now, I have it successfully compiling, but while it delays correctly in the loop and prints the correct messages in the serial monitor, it actually only sends a test message to the first number along with the AT commands to send to the next number (in the text message received by the first number) in this code I have included the receive message code yet, as I would like to get the loop working first before I try to break it.
//THis code is sending both messages to first number
#include <GSM.h>
#define PINNUMBER ""
const int buttonPin = 4;
const int ledPin1 = 13;
const int ledPin2 = 12;
int buttonState = 0;
// initialize the library instance
GSM gsmAccess; // include a 'true' parameter for debug enabled
GSM_SMS sms;
// char array of the telephone number to send SMS
const char* number1 = "xxxxxxxxxxxxx"; // enter any two mobile numbers here in international format
const char* number2 = "xxxxxxxxxxxxx";
// char array of the message
char txtMsg[200]="test";
// connection state
boolean notConnected = true;
void setup()
{
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(buttonPin, INPUT);
// initialize serial communications
Serial.begin(9600);
Serial.println("SMS Messages Sender");
// Start GSM shield
// If your SIM has PIN, pass it as a parameter of begin() in quotes
while(notConnected)
{
if(gsmAccess.begin(PINNUMBER)==GSM_READY)
notConnected = false;
else
{
Serial.println("Not connected");
delay(1000);
}
}
Serial.println("GSM initialized");
}
void loop()
{
buttonState = digitalRead(buttonPin);
{
sendSMS();
}
}
void sendSMS()
{
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
if(buttonState == HIGH) {
buttonState = 1;
};
if (buttonState == 1) {
digitalWrite(ledPin2, HIGH);
delay(1000);
Serial.print("Message to mobile number: ");
Serial.println(number1);
// sms text
Serial.println("SENDING");
Serial.println();
Serial.println("Message:");
Serial.println(txtMsg);
// send the message
sms.beginSMS(number1);
sms.print(txtMsg);
Serial.println("\nFirst Message Sent\n");
digitalWrite(ledPin2, LOW);
delay (60000);
digitalWrite(ledPin2, HIGH);
delay(1000);
Serial.print("Message to mobile number: ");
Serial.println(number2);
// sms text
Serial.println("SENDING");
Serial.println();
Serial.println("Message:");
Serial.println(txtMsg);
// send the message
sms.beginSMS(number2);
sms.print(txtMsg);
sms.endSMS();
Serial.println("\nSecond Message Sent\n");
digitalWrite(ledPin2, LOW);
}
}
Change GSM_sms;
to
GSM_smsone;
GSM_smstwo;
use
smsone.beginSMS(number1);
smsone.print(txtMsg);
smsone.endSMS();
smstwo.beginSMS(number2);
smstwo.print(txtMsg);
smstwo.endSMS();
for sending the sms.
#include <GSM.h>
#define PINNUMBER ""
const int buttonPin = 4;
const int ledPin1 = 13;
const int ledPin2 = 12;
int buttonState = 0;
// initialize the library instance
GSM gsmAccess; // include a 'true' parameter for debug enabled
GSM_SMS smsone;
GSM_SMS smstwo;
// char array of the telephone number to send SMS
const char* number1 = "xxxxxxxxxxxxx"; // enter any two mobile numbers here in international format
const char* number2 = "xxxxxxxxxxxxx";
// char array of the message
char txtMsg[200] = "test";
// connection state
boolean notConnected = true;
void setup()
{
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(buttonPin, INPUT);
// initialize serial communications
Serial.begin(9600);
Serial.println("SMS Messages Sender");
// Start GSM shield
// If your SIM has PIN, pass it as a parameter of begin() in quotes
while (notConnected)
{
if (gsmAccess.begin(PINNUMBER) == GSM_READY)
notConnected = false;
else
{
Serial.println("Not connected");
delay(1000);
}
}
Serial.println("GSM initialized");
}
void loop(){
buttonState = digitalRead(buttonPin);
{
sendSMS();
}
}
void sendSMS()
{
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
if (buttonState == HIGH) {
buttonState = 1;
};
if (buttonState == 1) {
digitalWrite(ledPin2, HIGH);
delay(1000);
Serial.print("Message to mobile number: ");
Serial.println(number1);
// sms text
Serial.println("SENDING");
Serial.println();
Serial.println("Message:");
Serial.println(txtMsg);
// send the first message
smsone.beginSMS(number1);
smsone.print(txtMsg);
smsone.endSMS();
Serial.println("\nFirst Message Sent\n");
digitalWrite(ledPin2, LOW);
delay (60000);
digitalWrite(ledPin2, HIGH);
delay(1000);
Serial.print("Message to mobile number: ");
Serial.println(number2);
// sms text
Serial.println("SENDING");
Serial.println();
Serial.println("Message:");
Serial.println(txtMsg);
// send the second message
smstwo.beginSMS(number2);
smstwo.print(txtMsg);
smstwo.endSMS();
Serial.println("\nSecond Message Sent\n");
digitalWrite(ledPin2, LOW);
}
}
So I hacked at a getFlow function for the Arduino sketch I am working on, and I am getting output of the function in the console of the iPhone, but when I hook up the computer to the Arduino, and open the serial monitor I don't see any output from the getFlow4 function. I am using a Swiss flow SF800 flowmeter / flowsensor.
/*
* kegboard-clone-4-KegCop
* This code is public domain
*
* This sketch sends a receives a multibyte String from the iPhone
* and performs functions on it.
*
* This Arduino sketch is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Public License
* along with this sketch. If not, see <http://www.gnu.org/licenses/>.
*
* Examples:
* http://arduino.cc/en/Tutorial/SerialEvent
* http://arduino.cc/en/Serial/read
* http://stackoverflow.com/questions/16532586/arduino-sketch-that-responds-to-certain-commands-how-is-it-done/
* http://davebmiller.wordpress.com/2011/01/18/arduino-flowmeter/
* http://forum.arduino.cc/index.php?topic=52003.0
* http://arduino.cc/en/Reference/AttachInterrupt
*
* TODO:
* - eventually get code working with the SF800 flow sensor / flowmeter
*
*/
// flow_A LED
int led = 4;
// relay_A
const int RELAY_A = A0;
// string / serial event variables
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
boolean valve_open = false;
// FLOWMETER SHIT
// flowmeter 0 pulse (input) = digital pin 2
// https://github.com/Kegbot/kegboard/blob/master/arduino/kegboard/kegboard_config.h
// which pin to use for reading the sensor? kegboard-mini shield has digital pin 2 allocated
// the SF800 outputs 5400 pulses per litre
// The hall-effect flow sensor (SF800) outputs approximately 5400 pulses per second per litre/minute of flow
int sensorInterrupt = 0; // changed from byte
int sensorPin = 2; // changed from byte
int sensorPinState = 0; // variable for storing state of sensor pin
// read RPM
int rpmcount = 0;
int rpm = 0;
unsigned long lastmillis = 0;
void setup() {
// initialize serial
// Serial.flush(); // flush the serial buffer on setup.
Serial.begin(115200); // open serial port, sets data rate to 9600bps
Serial.println("Power on test");
inputString.reserve(200);
valve_open = false;
// relay for solenoid cut off valve
pinMode(RELAY_A, OUTPUT);
// flowmeter shit
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, HIGH); // Need to set these HIGH so they won't just tick away
// The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
// Configured to trigger on a RISING state change (transition from HIGH
// state to LOW state)
attachInterrupt(0, rpm_fan, RISING);
}
void open_valve() {
digitalWrite(RELAY_A, HIGH); // turn RELAY_A on
valve_open = true;
}
void close_valve() {
digitalWrite(RELAY_A, LOW); // turn RELAY_A off
valve_open = false;
}
void flow_A_blink() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for one second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
void flow_A_blink_stop() {
digitalWrite(led, LOW);
}
void flow_A_on() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
}
void flow_A_off() {
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
}
// flowmeter shit
void getFlow4() {
// Serial.println("im here");
// Serial.println(sensorPin);
sensorPinState = digitalRead(sensorPin);
// Serial.println(sensorPinState);
if (millis() - lastmillis >= 1000){ //Uptade every one second, this will be equal to reading frecuency (Hz).
detachInterrupt(0);//Disable interrupt when calculating
rpm = rpmcount * 60; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.
Serial.print("RPM =\t"); //print the word "RPM" and tab.
Serial.print(rpm); // print the rpm value.
Serial.print("\t Hz=\t"); //print the word "Hz".
Serial.println(rpmcount); //print revolutions per second or Hz. And print new line or enter.
rpmcount = 0; // Restart the RPM counter
lastmillis = millis(); // Uptade lasmillis
attachInterrupt(0, rpm_fan, RISING); //enable interrupt
}
if(sensorPinState == LOW) {
flow_A_off();
Serial.println("don't blink");
}
if(sensorPinState == HIGH) {
flow_A_on();
Serial.println("blink damnit");
}
if(stringComplete) {
if(inputString.equals("{close_valve}\n")) {
// Serial.println("close vavle.");
close_valve();
}
return;
}
}
void rpm_fan(){
rpmcount++;
}
/*
* Main program loop, runs over and over repeatedly
*/
void loop() {
if(stringComplete) {
// Serial.println(inputString);
if(inputString.equals("{open_valve}\n")) {
// Serial.println("inputString equates :)");
open_valve();
}
if(inputString.equals("{close_valve}\n")) {
// Serial.println("close vavle.");
close_valve();
}
if(valve_open) {
// Serial.println("valve_open = true");
inputString = "";
stringComplete = false;
getFlow4();
}
// clear the string:
inputString = "";
stringComplete = false;
}
//Serial.println("over and over");
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while(Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
// Serial.println(inputString.length());
}
}
I have a project to program a microcontroller PIC18F, I have to connect a switching circuit to the microcontroller board, this switching circuit has an electric lock and a buzzer to be connected to it.
The lock is initially powered. It is supposed that when I send '1', the buzzer will be powered with a square wave and the lock will be powered off. When it receives '0', the buzzer will be switched off without powering the lock again. When it receives '2' the lock should be powered but if the buzzer was unpowered before, it should not be powered again.
My confusion is in the last part. When I send '2' via the hyperterminal, and I sent '0' before it, the buzzer is powered again.
Here is the code,
void buzzertest();
char uart_rd;
int buzzer;
void main() {
TRISB=0X00;
PORTB=0x00;
RB5_bit = 0xFF; //lock open
UART1_Init(9600); // Initialize UART module at 9600 bps
while (1) { // Endless loop
if (UART1_Data_Ready()) // If data is received,
{
buzzer=1;
uart_rd = UART1_Read(); // read the received data,
if(uart_rd =='1') {
RB5_bit = 0x00; //lock closed
buzzertest();
}
if(uart_rd =='0' ){ //disable buzzer
RB1_bit = 0x00; //buzzer
buzzer=0;
}//end if
buzzer=0;
if(uart_rd =='2'){ //disable lock
RB5_bit=0xFF;
if(buzzer!=1){
buzzertest();
}
}//end if
} //end outer if
} //end while
}//end main
void buzzertest(){
while(1){
RB1_bit = 0xFF; //buzzer
Delay_ms(1000);
RB1_bit = 0x00; //buzzer
Delay_ms(1000);
if (UART1_Data_Ready())
break;
}//end while loop
}
Can please anyone help me solving this?
You're setting buzzer to 0 outside the if(uart_rd='0') block. So when you come to the if(uart_rd='2') block, buzzer is always 0 and so the if(buzzer!=1) block is always called.
Have you tried stepping through this with a debugger? It would show up this kind of thing easily. You could also change those if blocks either to a switch statement or a series of if / else if statements to avoid these sorts of issues.
here is the running code:
void buzzertest();
char uart_rd;
int buzzer;
void main() {
TRISB=0X00;
PORTB=0x00;
RB5_bit = 0xFF; //lock open
UART1_Init(9600); // Initialize UART module at 9600 bps
while (1) { // Endless loop
if (UART1_Data_Ready()) // If data is received,
{
uart_rd = UART1_Read(); // read the received data,
if(uart_rd =='1') {
RB5_bit = 0x00; //lock closed
buzzertest();
buzzer=1 ;
}
else if(uart_rd =='0' ){ //disable buzzer
RB1_bit = 0x00; //buzzer
buzzer=0;
}//end else if
else if(uart_rd =='2'){ //disable lock
RB5_bit=0xFF;
if(buzzer==1){
buzzertest();
}
}//end else if
} //end outer if
} //end while
}//end main
void buzzertest(){
while(1){
RB1_bit = 0xFF; //buzzer
Delay_ms(1000);
RB1_bit = 0x00; //buzzer
Delay_ms(1000);
if (UART1_Data_Ready())
break;
}//end while loop
}