spi interfacing between two microcontroller in mikroC - mikroc

I'm doing spi interfacing between two pic18F452 microcontrollers in mikroC but my program doesn't give any output. I send a data from Master and slave have to display it on LCD.
Here is my code for both master and slave:
MASTER CODE:
unsigned char key='a';
void main(void)
{
TRISC.F2=0; //output for Slave select
TRISC.F3=0; //SCK output
TRISC.F4=1; //SDI input
TRISC.F5=0; //SDO output
Spi_Init_Advanced(Master_OSC_div64, Data_SAMPLE_MIDDLE, CLK_Idle_HIGH, HIGH_2_LOW);
SSPCON1.SSPEN=1; //Synchronus serial port enable
SSPSTAT.SMP=0; //sampled at middle of data output time
while(1)
{
PORTC.F2=0;
SSPBUF=key;
while(!SSPSTAT.bf);
spi_write(key);
}
}
///////end//////
SLAVE CODE:
#define LCD PORTB
unsigned char key;
void main(void)
{
TRISB=0; //LCD output
TRISC.F4=1; //SDI input
TRISC.F3=1; //SCK input from master
TRISC.F5=0; //SDO output
TRISA.F5=1; //Slave select input from master
SSPSTAT.SMP=0; //input data sampled at middle
SSPSTAT.CKE=0; // transition from idle to active
SSPCON1.=0x22;
Spi_Init_Advanced(SLAVE_SS_ENABLE, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH);
Lcd_init(&PORTB);
Lcd_cmd(Lcd_clear);
Lcd_cmd(Lcd_cursor_off);
while(1)
{
if(SSPSTAT.BF)
{
key=spi_read(SSPBUF);
}
}
}
////////end///////

i am not sure about this part
Lcd_init(&PORTB);
Lcd_cmd(Lcd_clear);
Lcd_cmd(Lcd_cursor_off);
try declaring your lcd port like this . i use port d
//lcd
sbit LCD_RS at RD0_bit;
sbit LCD_RW at RD1_bit;
sbit LCD_EN at RD2_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D4 at RD4_bit;
// Pin direction
sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_RW_Direction at TRISD1_bit;
sbit LCD_EN_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISD7_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD4_bit;
and for initing and clearing
LCD_Init(); // Initialize LCD
DELAY_MS(100);
Lcd_Cmd(_LCD_CLEAR); // Clear display
that delay part might comes handy some times.

Related

does PIC 16f877a external interrupt can affect all port?

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

Arduino PLC Modbus Communication to read plc input register

I am trying to communicate Arduino UNO and Wecon(LX3v-0806MR) PLC with RS485. Here the arduino is the master and the plc is the slave. I want to now read the values from the input registers (04) of plc and present it on serial monitor. For that purpose I am using the following code.
#include <ModbusMaster.h>
/*!
We're using a MAX485-compatible RS485 Transceiver.
Rx/Tx is hooked up to the hardware serial port at 'Serial'.
The Data Enable and Receiver Enable pins are hooked up as follows:
*/
#define MAX485_DE 3
#define MAX485_RE_NEG 2
// instantiate ModbusMaster object
ModbusMaster node;
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}
void setup()
{
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
// Modbus communication runs at 115200 baud
Serial.begin(115200);
// Modbus slave ID 1
node.begin(1, Serial);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
bool state = true;
void loop()
{
uint8_t result;
uint16_t data[6];
// Toggle the coil at address 0x0002 (Manual Load Control)
result = node.writeSingleCoil(0x0002, state);
state = !state;
// Read 16 registers starting at 0x3100)
result = node.readInputRegisters(0x3100, 16);
if (result == node.ku8MBSuccess)
{
Serial.print("Vbatt: ");
Serial.println(node.getResponseBuffer(0x04)/100.0f);
Serial.print("Vload: ");
Serial.println(node.getResponseBuffer(0xC0)/100.0f);
Serial.print("Pload: ");
Serial.println((node.getResponseBuffer(0x0D) +
node.getResponseBuffer(0x0E) << 16)/100.0f);
}
delay(1000);
}
I tried the codes many a times but it is not working. If anyone knows how to do it please share the codes with me. I just want read int value from plc.
*Note: The sensor used is for TTL to rs485 is MAX485.

XBee-Pro 900HP Communication in API Mode

I've been been trying to get an Xbee-Pro 900HP to communicate with another Xbee, but it doesn't seem to work. I've confirmed that the xbees are set up correctly as they can communicate remotely over XCTU, so it is either my code or my setup. I've gotten the setup checked by people I trust, so that really only leaves the code. Do you have any idea what I'm doing wrong? (Teensy 4.0, API 2 Mode)
#include <Printers.h>
#include <XBee.h>
//int test1 = 5;
XBee xbee = XBee();
//SoftwareSerial sserial(1,0);
//String altstring = String(alt);
uint8_t test1[]= {'H', 'i'};
//Tx16Request tx = Tx16Request(0xFFFE, packet, sizeof(packet));
void setup() {
Serial.begin(9600); //debug
Serial1.begin(9600);
Serial2.begin(9600);
xbee.setSerial(Serial1);
delay(1000);
Serial.println("Setup Complete\n");
Serial.println("Check Reciving radio Console");
}
void loop() {
Serial.println("test");
XBeeAddress64 addr64 = XBeeAddress64(0x13A200, 0x41DDEE70);
Tx64Request tx = Tx64Request(addr64, test1, sizeof(test1));
xbee.send(tx);
delay(5000);
}

Using shiftOut() with LSBFIRST bit order to send the data into the MAX7219 in Arduino

I have the following code:
#define MAX7219_Data_IN 11
#define MAX7219_Chip_Select 9
#define MAX7219_Clock 13
void shift(byte send_to_address, byte send_this_data)
{
digitalWrite(MAX7219_Chip_Select, LOW);
shiftOut(MAX7219_Data_IN, MAX7219_Clock, MSBFIRST, send_to_address);
shiftOut(MAX7219_Data_IN, MAX7219_Clock, MSBFIRST, send_this_data);
digitalWrite(MAX7219_Chip_Select, HIGH);
}
void init_max7219() //Setup of MAX7219 chip
{
shift(0x0f, 0x00); //display test register - test mode off
shift(0x0c, 0x01); //shutdown register - normal operation
shift(0x0b, 0x07); //scan limit register - display digits 0 thru 7
shift(0x0a, 0x0f); //intensity register - max brightness
shift(0x09, 0x00); //decode mode register - No decode
}
void setup()
{
pinMode(MAX7219_Data_IN, OUTPUT);
pinMode(MAX7219_Chip_Select, OUTPUT);
pinMode(MAX7219_Clock, OUTPUT);
digitalWrite(MAX7219_Clock, LOW);
init_max7219(); //init MAX2719 chip
shift(1, B01110111);
}
void loop() { }
I use shiftOut() to send the data into the MAX7219. I pass MSBFIRST as bit order parameter. It works fine. I use UnoArduSim and have the letter A in position 1 as expected. But I have problems with using LSBFIRST:
void shift(byte send_to_address, byte send_this_data)
{
digitalWrite(MAX7219_Chip_Select, LOW);
shiftOut(MAX7219_Data_IN, MAX7219_Clock, LSBFIRST, send_to_address);
shiftOut(MAX7219_Data_IN, MAX7219_Clock, LSBFIRST, send_this_data);
digitalWrite(MAX7219_Chip_Select, HIGH);
}
Nothing is displayed on the seven-segment indicators. How to use the Least Significant Bit First correctly?
In order to use LSBFIRST you need to change values passed to shiftOut. For example, change 0x0f (B00001111) to 0xf0 (11110000), 0x0c (00001100) to 0x30(00110000) so that the Least Significant Bit will be the first.
#define MAX7219_Data_IN 11
#define MAX7219_Chip_Select 9
#define MAX7219_Clock 13
void shift(byte send_to_address, byte send_this_data)
{
digitalWrite(MAX7219_Chip_Select, LOW);
shiftOut(MAX7219_Data_IN, MAX7219_Clock, LSBFIRST, send_to_address);
shiftOut(MAX7219_Data_IN, MAX7219_Clock, LSBFIRST, send_this_data);
digitalWrite(MAX7219_Chip_Select, HIGH);
}
void init_max7219() //Setup of MAX7219 chip
{
shift(0xf0, 0x00); //display test register - test mode off
shift(0x30, 0x80); //shutdown register - normal operation
shift(0xd0, 0xe0); //scan limit register - display digits 0 thru 7
shift(0x50, 0xf0); //intensity register - max brightness
shift(0x90, 0x00); //decode mode register - No decode
}
void setup()
{
pinMode(MAX7219_Data_IN, OUTPUT);
pinMode(MAX7219_Chip_Select, OUTPUT);
pinMode(MAX7219_Clock, OUTPUT);
digitalWrite(MAX7219_Clock, LOW);
init_max7219(); //init MAX2719 chip
shift(0x80, B11101110);
}
void loop() { }

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);
}
}

Resources