Digital Clock C code / PIC, Protues - microcontroller

I'm taking a Microcontroller course this semester, and I have an assignment to make a digital clock using PIC18 and display it on LCD. My code is in C and I'm protues to simulate.
I wrote a code but something is wrong if anyone can help me figure out my mistake..
Thank you
#include <P18F4580.h>
#define ldata PORTD
#define rs PORTBbits.RB0
#define rw PORTBbits.RB1
#define en PORTBbits.RB2
void msdelay(unsigned int itime)
{ unsigned int i,j;
for (i=0; i<itime; i++)
for (j=0; j<135; j++);
}
void lcdcmd(unsigned char value)
{ ldata = value;
rs = 0;
rw = 0;
en = 1;
msdelay(1);
en = 0;
}
void lcddata(unsigned char value)
{ ldata = value;
rs = 1;
rw = 0;
en = 1;
msdelay(1);
en = 0;
}
void main()
{
TRISD = 0;
TRISB = 0;
en = 0;
int msCounter =0;
int secCounter =0;
int minCounter =0;
int hrCounter =0;
msdelay(15);
lcdcmd(0x01); //Clear display
msdelay(15);
lcdcmd(0x02); //Home cursor
msdelay(15);
lcdcmd(0x06); //Left to right, still
msdelay(250);
lcdcmd(0x0E); //display cursor
msdelay(250);
lcdcmd(0x3C); //5x10 2 lines
msdelay(15);
lcdcmd(0x86);
while(1)
{
msdelay(15);
lcdcmd(0x08);
lcddata(secCounter);
msdelay(15);
msCounter++;
if (msCounter==1000)
{secCounter++; msCounter=0; }
if (secCounter==60)
{minCounter++; secCounter=0; }
if (minCounter==60)
{hrCounter++; minCounter=0; }
if (hrCounter==24)
{hrCounter=0; }
msdelay(15);
lcddata(hrCounter);
msdelay(15);
lcddata(':');
msdelay(15);
lcddata(minCounter);
msdelay(15);
lcddata(':');
msdelay(15);
lcddata(secCounter);
}
}

Its better to display digital clock using 7-segment display than in LCD.

use this code in your program and check...
for lcddata(mscounter);
use *thous(mscounter);*
declare it in the code and check
lcdcmd(0x08); instead use
lcdcmd(0x80);
void thous(unsigned int count)
{
lcddata((count/1000)+0x30);
lcddata(((count/100)%10)+0x30);
lcddata(((count%100)/10)+0x30);
lcddata((count%10)+0x30);
}

Related

why my audio sound is not playing in my arduino code but if i play it separately it started working good

I am trying to set the timer after which the audio will automatically played once but it is not playing anything just a noise but when i run the audio program separately it work perfectly good
This is my code please help me out where i am doing wrong.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>
#include <TMRpcm.h>
#include <SPI.h>
int timer1_counter;
#define SD_ChipSelectPin 4
TMRpcm tmrpcm;
unsigned long time_now = 0;
LiquidCrystal_I2C lcd(0x27, 16, 2);
const byte ledPin = 13;
const byte interruptPin1 = 2;
const byte interruptPin2 = 3;
int counter2 = 0;
volatile byte state = LOW;
int count = 0;
int limit = 0;
bool TimerFlag = false;
int deviceTime = 0;
int set = 5;
bool soundplayflag = false;
void setup()
{
lcd.begin();
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(interruptPin1, INPUT_PULLUP);
pinMode(interruptPin2, INPUT_PULLUP);
pinMode(set, INPUT_PULLUP);
lcd.backlight();
lcd.setCursor(1,0);
lcd.print("Please Select:");
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 31250; // compare match register 16MHz/256/2Hz
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts
// initialize timer1
}
ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine
{
if (soundplayflag == true)
{
counter2 = counter2+1;
Serial.println(counter2/2);
}
}
void loop()
{
//unsigned long currentMillis = millis();
int up = digitalRead(interruptPin1);
int down = digitalRead(interruptPin2);
int setbutton = digitalRead(set);
delay(230);
if (up == 0)
{
Serial.println("Entering up");
count++;
if (count >= 0) {
lcdprint(count);
}
}
else if (down == 0)
{
Serial.println("Entering down");
count--;
if (count >= 0) {
lcdprint(count);
}
}
else if (setbutton == 0)
{
Serial.println("Entering set");
soundplayflag=true;
deviceTime = count;
}
if (deviceTime > 0)
{
if (deviceTime == counter2)
{
soundplayflag=false;
Serial.println("Hello world");
PlaySound();
counter2 = 0;
}
}
}
int lcdprint(int a)
{
lcd.clear();
lcd.setCursor(1,0);
lcd.print("Please Select:");
lcd.setCursor (7,1);
lcd.print(a);
Serial.println(a);
lcd.setCursor (10,1);
lcd.print("Min");
}// end of lcdprint(int a)
void PlaySound()
{
for (int i = 0; i < 10; i++)
{
tmrpcm.setVolume(5);
tmrpcm.play("3.wav");
delay(1000);
}// end of for loop
}// end of void PlaySound()
my expected output is it should play the sound when i set the time
It seems TMRpcm uses Timer1, which conflicts with your TIMER1_COMPA_vect. That would explain why it's working if you run nothing else.
Maybe try to use #define USE_TIMER2?

invalid conversion from 'int*' to 'uint8_t

im having a problem, i just bought an arduino and i was wondering if anyone could help, here is my code. (i am just trying to get two leds to fade in and out).
int ledCount = 2;
int ledPins [ ] = {11,12 };
int brightness = 0;
int delayTime = 10;
void setup() {
pinMode(ledPins, OUTPUT);
}
void loop() {
while(brightness < 255)
{
analogWrite(ledPins, brightness);
delay(delayTime);
brightness = brightness + 1;
}
while(brightness > 0)
{
analogWrite(ledPins, brightness);
delay(delayTime);
brightness = brightness - 1;
}
}
You are passing an array to analogWrite or pinMode, where it is expecting a uint8_t.
Arduino pin manipulation functions will only handle a single pin at a time. There are ways around that, by directly manipulating the AVR/ARM GPIO registers, but those can be finicky (not recommended for use unless you really need speed).
The reason it says int * is because under the hood, arrays in C/C++ are represented as pointers.
If you want to analogWrite or pinMode to both LEDs, you will have to call the function once for each LED. Example:
analogWrite(ledPins[0], brightness);
analogWrite(ledPins[1], brightness);
Or
for(int currentLED = 0;currentLED < ledCount;i++){
analogWrite(ledPins[currentLED], brightness);
}
In the context of your program:
int ledCount = 2;
int ledPins [] = {11, 12};
int brightness = 0;
int delayTime = 10;
#define INCREASE 1
#define DECREASE 2
int brightness_change = INCREASE;
void setup(){
for(int i = 0;i < ledCount;i++){
pinMode(i, OUTPUT);
}
}
void loop(){
while(brightness < 255 && brightness_change == INCREASE){
brightness = brightness + 1;
}
while(brightness > 0 && brightness_change == DECREASE){
brightness = brightness - 1;
}
if(brightness == 255){
brightness_change = DECREASE;
}
if(brightness == 0){
brightness_change = INCREASE;
}
for(int current_led = 0;current_led < ledCount;current_led++){
analogWrite(current_led, brightness;
}
delay(delayTime;
}
Not tested, but it should work.

How to use buffer to read and write using serial port in 8051 MCU

I am using keil c51 compiler. I transmit data from my pc to MCU using serial port it works best.
When I transmit data from my MCU to PC then also it works best.
But when I transmit data to MCU and then store it to buffer character pointer and again from that character pointer buffer I transmit return to PC then it does not work and give garbage values?
My code for both function as below.
#include <REG51.H>
#include "uart.c"
void delay_ms(unsigned int x) // delays x msec (at fosc=11.0592MHz)
{
unsigned char j=0;
while(x-- > 0)
{
for (j=0; j<125; j++){;}
}
}
sbit SW = P3^2;
sbit LED = P3^3;
bit x = 0;
void main ()
{
char *buf;
int len=0;
int len1 = 0;
uart_init();
while(1){
if(RI == 1){
UART_RxString(buf,&len);
buf -= (len-1) ;
x = 1;
}
if(x == 1 && SW == 0){
UART_TxString(buf,&len1);
x = 0;
}
}
}
And below are the functions.
1.
void UART_TxString(char *string_ptr, int *l)
{
int count = 0;
while(*string_ptr){
UART_TxChar(*string_ptr++);
count++;
}
*l = count;
}
void UART_RxString(char *string_ptr, int *l)
{
char ch;
int count = 0;
while(1)
{
ch=UART_RxChar(); //Reaceive a char
//UART_TxChar(ch); //Echo back the received char
count++;
if((ch=='\r') || (ch=='\n')) //read till enter key is pressed
{ //once enter key is pressed
*string_ptr=0; //null terminate the string
break; //and break the loop
}
*string_ptr=ch; //copy the char into string.
string_ptr++; //and increment the pointer
}
*l = count;
}

Arduino memory game

This game has 4 leds and 4 buttons. the game is turning RANDOMLY those leds ON and OFF.
The player should be able to push the right button whenever he sees one led to be turned ON.
The leds should be turning ON and OFF with incerasing speed, so reaction time of a player is shorter and shorter
I have this code but i just know how to add more leds and buttons.
const int BUTTON1 = A0;
const int BUTTON2 = A1;
const int BUTTON3 = A2;
const int BUTTON4 = A3;
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int ran;
int right = 0;
int ledOrder[9];
int guessOrder[9];
void setup()
{
Serial.begin(9600);
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
pinMode(LED3,OUTPUT);
pinMode(LED4,OUTPUT);
pinMode(BUTTON1,INPUT);
pinMode(BUTTON2,INPUT);
pinMode(BUTTON3,INPUT);
pinMode(BUTTON4,INPUT);
}
void randomLed() {
for (int i = 0; i < 9; i++) {
ran = random(1,20);
if (ran < 11) {
digitalWrite(LED1,HIGH);
delay(500);
digitalWrite(LED1,LOW);
ledOrder[i] = 1;
}
else {
digitalWrite(LED2,HIGH);
delay(500);
digitalWrite(LED2,LOW);
ledOrder[i] = 2;
}
delay(500);
}
}
void btnClick() {
int ans = 0;
while (ans < 9) {
if (digitalRead(BUTTON1) == HIGH) {
guessOrder[ans] = 1;
ans++;
while (digitalRead(BUTTON1) == HIGH) {
}
}
else if (digitalRead(BUTTON2) == HIGH) {
guessOrder[ans] = 2;
ans++;
while (digitalRead(BUTTON2) == HIGH) {
}
}
}
}
void loop() {
Serial.print("Press button1 to start \n");
while (digitalRead(BUTTON1) == LOW) {
}
randomLed();
btnClick();
for (int i = 0; i < 9; i = i + 1) {
Serial.print("Guess: ");
Serial.print(guessOrder[i]);
Serial.print(" Answer: ");
Serial.print(ledOrder[i]);
if (guessOrder[i] == ledOrder[i]) {
Serial.print(" Right");
right++;
} else {
Serial.print(" Wrong");
}
Serial.print("\n ");
}
Serial.print(right);
Serial.print("/9\n");
delay(2000);
}
If I understand your question correctly, you would like to increase the led blink rate(when the LED's come on) each time the user gets the previous game right. If this is true you should try to put loop in for/if the user got the the previous one(game) right it will increase blink rate by a simple increment( I++;). Comment if you feel this is clarified enough or if your asking for something else

Why doesn't my servo control work?

Basically I'm trying to control a servo with two push buttons (one for forward and one for backward). However, my code doesn't work and I am not sure why. Essentially I used the Sweep and Button examples to make this code. However, it doesn't seem to be working unless something is wrong with my hookup.
#include <Servo.h>
Servo servoOne;
int servoOnePos = 0;
const int buttonUpPin = 13;
const int buttonDownPin = 12;
int buttonUpState = 0;
int buttonDownState = 0;
void setup() {
servoOne.attach(11);
pinMode(buttonUpPin, INPUT);
pinMode(buttonDownPin, INPUT);
}
void loop() {
buttonUpState = digitalRead(buttonUpPin);
buttonDownState = digitalRead(buttonDownPin);
if (buttonUpState == HIGH) {
for (servoOnePos < 180; servoOnePos += 1;) {
servoOne.write(servoOnePos);
delay(15);
}
} else if (buttonDownState == HIGH) {
for (servoOnePos <= 180; servoOnePos = servoOnePos - 1;) {
servoOne.write(servoOnePos);
delay(15);
}
}
}
#include <Servo.h>
Servo servoOne;
int pos = 90;
const int maxDeg = 160;
const int minDeg = 5;
const int buttonUpPin = 13;
const int buttonDownPin = 12;
const int leftPin = 3;
const int rightPin = 2;
int leftPressed = 0;
int rightPressed = 0;
void setup()
{
servoOne.attach(11);
pinMode(buttonUpPin, INPUT);
pinMode(buttonDownPin, INPUT);
}
void loop()
{
leftPressed = digitalRead(leftPin);
rightPressed = digitalRead(rightPin);
if(leftPressed){
if(pos < maxDeg) {
pos += 3;
}
servoOne.write(pos);
}
if(rightPressed){
if(pos > minDeg) {
pos -= 3;
}
servoOne.write(pos);
}
delay(15);
}

Resources