does PIC 16f877a external interrupt can affect all port? - microcontroller

the circuitI was working with PIC 16f877a and LCD, I want to powering a motor with transistor that used for relay with 9v battery and my LCD become error, does this because external interrupt?, because i used the external interrupt for a button on other port
I already change the program but its doesn't working and my LCD always display random character when the transistor is switching with 9v battery
int SetMoist=85;
int SetMoistR=0;
int SetMoistL=0;
int cset=0;
int sensingCounter=0;
int screenCounter=0;
int getMoist=0;
char *buffer = "00";
int turnON=1;
#define LCD_ON lcd_cmd(_LCD_TURN_ON);
#define LCD_OFF lcd_cmd(_LCD_TURN_OFF);
//LCD
sbit LCD_RS at RC1_bit;
sbit LCD_EN at RC2_bit;
sbit LCD_D4 at RC3_bit;
sbit LCD_D5 at RC4_bit;
sbit LCD_D6 at RC5_bit;
sbit LCD_D7 at RC6_bit;
sbit LCD_RS_Direction at TRISC1_bit;
sbit LCD_EN_Direction at TRISC2_bit;
sbit LCD_D4_Direction at TRISC3_bit;
sbit LCD_D5_Direction at TRISC4_bit;
sbit LCD_D6_Direction at TRISC5_bit;
sbit LCD_D7_Direction at TRISC6_bit;
//End of LCD
void interrupt() {
//Hardware interrupt flag
if(INTCON.b0 ==1){
turnON=1;
if(portb.b7==1){
if(SetMoist==99)
{}
else{
SetMoist++;
cset=0;
}
}
if(portb.b6==1){
turnON=1;
if(SetMoist==5)
{}
else{
SetMoist--;
cset=0;
}
}
if(portb.b5==1){
turnON=1;
portc.b0 =!portc.b0;
}
intcon.b0=0;
}
if(portb.b4==1){
turnON=1;
}
//End of Hardware interrupt flag
// Timer0 flag
if(INTCON.b2 ==1){
sensingCounter++;
screenCounter++;
//2 minutes timer for moisture
if(sensingCounter==50){
sensingCounter=0;
getMoist=ADC_Read(0);
getMoist=(getMoist/1024.0)*100.0;
if(getMoist>setMoist){
portc.b0=0b1;
}
else if(getMoist<setMoist){
portc.b0=0b0;
}
} //end moisture
if(screenCounter==1000){
screenCounter=0;
turnON=0;
}
intcon.b2=0;
}
//End of timer0 flag
//interrupt
}
void main() {
INTCON = 0b10101000;
//Timer0
option_reg= 0b10000111;
//TMR0=0;
//End of timer0
trisb= 0b11111111;
trisd = 0b00000000;
trisc.b7 =0;
trisc.b0=0;
portc.b0=0;
portd.b7=1;
portc.b7= 1;
trisa=0xff;
Lcd_Init();
lcd_cmd(_LCD_CURSOR_OFF);
lcd_out(1,1,"PENYIRAM TANAMAN");
lcd_out(2,5,"OTOMATIS");
delay_ms(1500);
Lcd_cmd(_LCD_CLEAR);
lcd_cmd(_LCD_CURSOR_OFF);
lcd_out(1,3,"DENGAN CINTA");
lcd_out(2,4,"KELOMPOK 2");
delay_ms(1500);
Lcd_cmd(_LCD_CLEAR);
lcd_cmd(_LCD_CURSOR_OFF);
lcd_out(1,3,"MENGHITUNG");
lcd_out(2,2,"KEKERINGAN...");
delay_ms(1500);
lcd_cmd(_LCD_CLEAR);
lcd_out(1,4,"KEKERINGAN:");
while(1){
if(cset==0){
cset=1;
//calculate R
SetMoistR= SetMoist % 10;
switch (SetMoistR) {
case 0: SetMoistR=0x3F; break;
case 1: SetMoistR=0x06; break;
case 2: SetMoistR=0x5B; break;
case 3: SetmoistR=0x4F; break;
case 4: SetmoistR=0x66; break;
case 5: SetmoistR=0x6D; break;
case 6: SetmoistR=0x7D; break;
case 7: SetmoistR=0x07; break;
case 8: SetmoistR=0x7F; break;
case 9: SetmoistR=0x6F; break;
}
// end of R calculation
//calculate L
SetMoistL= (SetMoist/10) % 10;
switch (SetMoistL) {
case 0: SetMoistL=0x3F; break;
case 1: SetMoistL=0x06; break;
case 2: SetMoistL=0x5B; break;
case 3: SetmoistL=0x4F; break;
case 4: SetmoistL=0x66; break;
case 5: SetmoistL=0x6D; break;
case 6: SetmoistL=0x7D; break;
case 7: SetmoistL=0x07; break;
case 8: SetmoistL=0x7F; break;
case 9: SetmoistL=0x6F; break;
}
//end of L calculation
}
//7Segment
portd=SetmoistR;
portc.b7=0;
portd.b7=1;
delay_ms(100);
portd=SetmoistL;
portd.b7=0;
portc.b7=1;
delay_ms(50);
//End_7Segment
//IntToStr(getMoist,buffer);
buffer[0] = (getMoist/10)%10 +48;
buffer[1] = (getMoist)%10+48;
lcd_chr(2,8,buffer[0]);
lcd_chr(2,9,buffer[1]);
lcd_chr(2,11,'%');
if(turnON==1){
LCD_ON;
}
else{
LCD_OFF;
}
} //while
} //main

Related

LED Won't turn off when output mode is set to LOW

I am making an alarm system using an ultrasonic distance sensor. It can be armed and disarmed using a remote, and I want a green led to be on when it is disarmed, and a red led to be on when it is armed. The red led works fine, but the green one stays on.
I have tried commenting out the line that turns on the green led, but it seems to be on by default, so when I start the program, it is already on and won't turn off. The code in question is near the bottom, marked by a comment that says //HERE
#include "IRremote.h"
#include "SR04.h"
#define TRIG_PIN 12
#define ECHO_PIN 11
SR04 sr04 = SR04(ECHO_PIN,TRIG_PIN);
long distance;
int receiver = 10;
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results; // create instance of 'decode_results'
int buzzer = 3;
int red_led = 2;
int green_led = 0;
bool can_sense = false;
bool release_pressed = false;
bool alarm_off = false;
/*-----( Function )-----*/
void translateIR() // takes action based on IR code received
// describing Remote IR codes
{
switch(results.value)
{
case 0xFFA25D: Serial.println("POWER"); alarm_off = true; break;
case 0xFFE21D: Serial.println("FUNC/STOP"); break;
case 0xFF629D: Serial.println("VOL+"); break;
case 0xFF22DD: Serial.println("FAST BACK"); break;
case 0xFF02FD: Serial.println("PAUSE"); release_pressed = true; break;
case 0xFFC23D: Serial.println("FAST FORWARD"); break;
case 0xFFE01F: Serial.println("DOWN"); break;
case 0xFFA857: Serial.println("VOL-"); break;
case 0xFF906F: Serial.println("UP"); break;
case 0xFF9867: Serial.println("EQ");release_pressed = false; break;
case 0xFFB04F: Serial.println("ST/REPT"); break;
case 0xFF6897: Serial.println("0"); break;
case 0xFF30CF: Serial.println("1"); break;
case 0xFF18E7: Serial.println("2"); break;
case 0xFF7A85: Serial.println("3"); break;
case 0xFF10EF: Serial.println("4"); break;
case 0xFF38C7: Serial.println("5"); break;
case 0xFF5AA5: Serial.println("6"); break;
case 0xFF42BD: Serial.println("7"); break;
case 0xFF4AB5: Serial.println("8"); break;
case 0xFF52AD: Serial.println("9"); break;
case 0xFFFFFFFF: Serial.println(" REPEAT");break;
default:
Serial.println(" other button ");
}// End Case
delay(100);
}
void setup() {
Serial.begin(9600);
pinMode(buzzer,OUTPUT);
pinMode(red_led,OUTPUT);
pinMode(green_led,OUTPUT);
irrecv.enableIRIn();
}
void loop() {
if (irrecv.decode(&results)) // have we received an IR signal?
{
translateIR();
irrecv.resume(); // receive the next value
}
distance = sr04.Distance();
if (distance < 70)
{
can_sense = true;
}
if (can_sense==true and release_pressed==false)
{
while (alarm_off==false)
{
digitalWrite(buzzer,HIGH);
digitalWrite(red_led,HIGH);
delay(500);
digitalWrite(buzzer,LOW);
digitalWrite(red_led,LOW);
delay(250);
if (irrecv.decode(&results)) // have we received an IR signal?
{
translateIR();
irrecv.resume(); // receive the next value
}
}
}
if (release_pressed==false) //HERE
{
digitalWrite(red_led,HIGH);
digitalWrite(green_led,LOW); // This should turn off the green led, but it doesn't
}
if (release_pressed==true)
{
digitalWrite(red_led,LOW);
digitalWrite(green_led,HIGH);
}
alarm_off = false;
can_sense = false;
}
Thanks for any help :)
Pins 0 and 1 on an Uno are used for serial communication.
As soon as you did Serial.begin(9600);, you enabled those pins for serial comms, so you can't also use them as standard digital pins.
Simply use another pin for your green LED.

Power button IRremote

I am creating 3 LEDs that will light up by a remote. I am able to light up the LEDs individually but I need the power button to shut off all of the LEDs. How can I create a 4th case to turn off all LEDs?
#include <IRremote.h>
int RECV_PIN = 3; // the pin where you connect the output pin of TSOP4838
int led1 = 2;
int led2 = 4;
int led3 = 7;
int itsONled[] = {0,0,0,0};
/* the initial state of LEDs is OFF (zero)
the first zero must remain zero but you can
change the others to 1's if you want a certain
led to light when the board is powered */
#define code1 12495 // code received from button A
#define code2 6375 // code received from button B
#define code3 31365 // code received from button C
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600); // you can comment this line
irrecv.enableIRIn(); // Start the receiver
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
}
void loop() {
if (irrecv.decode(&results)) {
unsigned int value = results.value;
switch(value) {
case code1:
if(itsONled[1] == 1) { // if first led is on then
digitalWrite(led1, LOW); // turn it off when button is pressed
itsONled[1] = 0; // and set its state as off
} else { // else if first led is off
digitalWrite(led1, HIGH); // turn it on when the button is pressed
itsONled[1] = 1; // and set its state as on
}
break;
case code2:
if(itsONled[2] == 1) {
digitalWrite(led2, LOW);
itsONled[2] = 0;
} else {
digitalWrite(led2, HIGH);
itsONled[2] = 1;
}
break;
case code3:
if(itsONled[3] == 1) {
digitalWrite(led3, LOW);
itsONled[3] = 0;
} else {
digitalWrite(led3, HIGH);
itsONled[3] = 1;
}
break;
}
Serial.println(value); // you can comment this line
irrecv.resume(); // Receive the next value
}
}

how to interface ultrasonic sensor hc-sr04 with easyPic v7 microcontroller

Good evening guys!
Is there anyone who have an idea about how to interface ultrasonic sensor with pic microcontroller easyPic v7 with PIC18F45K22 chip, in order to make person counter.
I found a useful code and I tried to edit it but still it's not working...
Here is my code:
// Lcd module connections
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
void main()
{
int a;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,5,"ITCE444");
Lcd_Out(2,3,"Term Project");
Delay_ms(3000);
Lcd_Cmd(_LCD_CLEAR);
TRISA.RA0 = 0; //RB0 as Input PIN (TRG)
TRISA.RA4 = 0; //RB4 as Input PIN (ECHO)
while(1)
{
if(PORTA.RA4==1 && PORTA.RA0==1)
{
a = a + 1;
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"Person in: ");
Lcd_Out(1,12,a);
Lcd_Out(1,15,"Person");
}
else
{
a = a - 1;
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"Person out: ");
Lcd_Out(1,13,a);
}
Delay_ms(400);
}
}
Thanks and regards..
The code that you have posted above is 100% incorrect. Here is how the code is supposed to look like.
HC-SR04 is an ultrasonic distance sensor. It measures the distance between the sensor and an obstacle. While you can definitely use the distance information to make a counter, it seems like that is a little above your skillset.
So have three options:
Learn to use pic micro-controllers and write a lot of timer code
to get the distance reading from the sensor.
Switch to Arduino and use it's builtin libraries to get the
distance.
Change your hardware. You do not need an ultrasonic sensor (or a
microcontroller for that matter) to make a person counter. I suggest
you simply use a pair of infrared leds to make yourself a simple
circuit that gives a pulse when a person walks though them.
Thanks for you reply Mr Hassan Nadeem, I have an update for the code and it's almost work when I implemented it.
Have a look and tell me what you think:
// LCD module connections
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
// Ultrasonic module connection
sbit Ultrasonic at RD0_bit;
sbit Ultrasonic_Direction at TRISD0_bit;
// End of Ultrasonic module connections
#define Pole_Height 200
void main()
{
unsigned long Tm;
unsigned char Tl, Th;
unsigned int h, Person_Height,dist;
char Txt[7];
int cont =0 ;
ANSELB = 0;
ANSELD = 0;
Lcd_Init();
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(2,3,"Term Project");
Lcd_Out(1,5,"ITCE444");
Delay_Ms(2000);T0CON = 0x00;
for(;;)
{
Ultrasonic_Direction = 0;
TMR0H = 0;
TMR0L = 0;
Ultrasonic = 0;
Delay_us(3);
Ultrasonic = 1;
Delay_us(10);
Ultrasonic = 0;
while(PORTD.RD5 == 0);
T0CON.TMR0ON = 1;
while(PORTD.RD5 == 1);
T0CON.TMR0ON = 0;
Tl = TMR0L;
Th = TMR0H;
Tm = Th*256 + Tl;
Tm = Tm / 2;
Tm = 34 * Tm;
Tm = Tm / 1000;
h = (unsigned int)Tm;
Person_Height= Pole_Height - h;
if (Person_Height > 168 && Person_Height < 196)
cont = cont + 1 ;
else if(Person_Height > 132 && Person_Height < 160 && cont>0)
cont = cont - 1 ;
IntToStr(cont, Txt);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1, "Person in");
Lcd_Out(2,1, Txt);
Delay_Ms(1000);
}
}

Action is being performed three times

I am creating an Arduino project that plays Rock Paper Scissors.
I have a part of the code reading the value of the button and whenever I click only one button, it outputs three times (View code and images of serial monitor to understand what I mean, I can't really explain it)
Here is my code:
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin1 = A0; // the number of the pushbutton pin
const int buttonPin2 = A1;
const int buttonPin3 = A2;
const int ledPin = 12; // the number of the LED pin
// variables will change:
int buttonState1 = 0; // variable for reading the pushbutton status
int buttonState2 = 0;
int buttonState3 = 0;
char * choices[3] = {"Rock", "Paper", "Scissors"};
char * finalResult[3] = {"You Lost", "You Won!", "It's a Tie"};
byte Human = 0, Computer = 0, FR = 0;
char result[25];
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
digitalWrite(ledPin,LOW);
Serial.begin(9600);
unsigned long R;
randomSeed(R);
}
void loop(){
int choice = random(1,4);
int pick;
// read the state of the pushbutton value:
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
Serial.println("Entering Reading Loop...");
while(true)
{
buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);
if (buttonState1 == HIGH && buttonState2 == LOW && buttonState3 == LOW) {
// turn LED on:
Throw('1');
} else if (buttonState1 == LOW && buttonState2 == HIGH && buttonState3 == LOW) {
// turn LED on:
pick = 2; //Paper
Throw('2');
}else if (buttonState1 == LOW && buttonState2 == LOW && buttonState3 == HIGH) {
// turn LED on:
pick = 3; //Scissor
Throw('3');
}
}
}
void Throw(char H)
{
bool thrown = false;
H -= '0'; //convert ascii to decimal
H -= 1; // instead of 1,2,3, H is now 0,1,2
byte C = random(0, 3);
sprintf(result, "The Computer chose: %s, You chose: %s", choices[C], choices[H]);
Serial.println(result);
if ( C == H)
Serial.println(F("Its a TIE"));
else
{
switch (C)
{
case 0:
switch (H)
{
case 1:
Serial.println(F("Paper wraps Rock, You WIN!"));
Human++;
break;
case 2:
Serial.println(F("Rock crushes Scissors, You LOSE!"));
Computer++;
break;
}
break;
case 1:
switch (H)
{
case 0:
Serial.println(F("Paper wraps Rock, You LOSE!"));
Computer++;
break;
case 2:
Serial.println(F("Scissors cuts Paper, You WIN!"));
Human++;
break;
}
break;
case 2:
switch (H)
{
case 0:
Serial.println(F("Rock crushes Scissors, You WIN!"));
Human++;
break;
case 1:
Serial.println(F("Scissors cuts Paper, You LOSE!"));
Computer++;
break;
}
break;
}
}
}
This is what I'm getting on the serial monitor when I click only ONE button(the rock button)
http://gyazo.com/ceb5c8329993339368cf5d52181ed4d7
As you can see, it chooses the right option for the button but it calls the throw function 3 times.
http://playground.arduino.cc/Main/RockPaperScissors)
From the Arduino docs they recommend using a Debounce strategy for handling inputs.
Without debouncing, pressing the button once can appear to the code as
multiple presses.
http://www.arduino.cc/en/Tutorial/Debounce
Here is another example illustrating the Debounce technique:
http://danthompsonsblog.blogspot.com/2011/12/arduino-push-button-onoff-example.html
There are pull-up resistors built in to the arduino that will allow you to filter out the erratic electrical signal you get when pressing a button. See the section on INPUT_PULLUP here.
I don't what the exact issue was but, I added a delay in my throw function and it stopped outputting the serial print statement 3 times!
Here is my updated function:
void Throw(char H)
{
bool thrown = false;
H -= '0'; //convert ascii to decimal
H -= 1; // instead of 1,2,3, H is now 0,1,2
byte C = random(0, 3);
sprintf(result, "The Computer chose: %s, You chose: %s", choices[C], choices[H]);
Serial.println(result);
delay(500);
if ( C == H)
Serial.println(F("Its a TIE"));
else
{
switch (C)
{
case 0:
switch (H)
{
case 1:
Serial.println(F("Paper wraps Rock, You WIN!"));
Human++;
break;
return;
case 2:
Serial.println(F("Rock crushes Scissors, You LOSE!"));
Computer++;
break;
}
break;
case 1:
switch (H)
{
case 0:
Serial.println(F("Paper wraps Rock, You LOSE!"));
Computer++;
break;
case 2:
Serial.println(F("Scissors cuts Paper, You WIN!"));
Human++;
break;
}
break;
case 2:
switch (H)
{
case 0:
Serial.println(F("Rock crushes Scissors, You WIN!"));
Human++;
break;
case 1:
Serial.println(F("Scissors cuts Paper, You LOSE!"));
Computer++;
break;
}
break;
}
}
}

Communicating with Arduino Serial

I am trying to communicate with my Arduino over the USB port by using Serial:
int previous;
int current = 0;
void turnOn(int pinNumber){
previous = current;
current = pinNumber;
if(previous!=0){
digitalWrite(previous, LOW);
digitalWrite(current, HIGH);
}else{
digitalWrite(current, HIGH);
}
}
void setup(){
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
Serial.begin(9600);
Serial.write(1);
}
void loop(){
delay(1);
if(Serial.available()>0){
switch(Serial.read()){
case 0:
turnOn(8);
break;
case 1:
turnOn(9);
break;
case 2:
turnOn(10);
break;
default:
Serial.println(Serial.read());
}
}
}
I am trying so that if I send a 0 the rightmost LED will light up, if I send 1, the middle one will and if I send a 2 the leftmost will. However when I send 0,1 or anything else it prints a -1 meaning the default switch has been triggered. How do I fix it?
Try this...
void loop(){
if (Serial.available()) {
char input = Serial.read();
if(input == '0'){
turnOn(8);
}else if(input == '1'){
turnOn(9);
}else if(input == '2'){
turnOn(10);
}
}
}
Tell me if it works or not then we can proceed :)

Resources