Category Archives: Contoh-contoh Aplikasi

Contoh Kode Arduino Akses Pintu dengan RFID

Untuk Teori dasar RFID  mifare bisa dibaca disini
#include <SPI.h>
#include <MFRC522.h>

#define selenoid 4
#define RST_PIN 9
#define SS_PIN 10
#define jumlahdatabaseTAG 5

MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.

MFRC522::MIFARE_Key key; // prepare struct key for authentification

/**
* Initialize.
*/

char* databaseTAG[] =
{
“123456789ABCDE1”,// Tag 0
“123456789ABCDE2”,// Tag 1
“123456789ABCDE3”, // Tag 2
“123456789ABCDE4”, // Tag 3
“123456789ABCDE5”, // Tag 4
“123456789ABCDE6”, // Tag 5
“123456789ABCDE7”, // Tag 6
“123456789ABCDE8”, // Tag 7
“123456789ABCDE9”, // Tag 8
“123456789ABCDEF”, // Tag 9
};

char* Name[] =
{
“abdullah”, // Tag 1
“dodi”, // Tag 2
“uus”,
“yudi”,
“mario”,
“usman”,
“fatih”,
“fayiz”,
“herman”,
“dede”,

// Tag 3
};

int led1 = 5;
int led2= 6;
int pintu = 7;
int buzzer = 8;

void setup() {

pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(pintu, OUTPUT);
pinMode(buzzer, OUTPUT);

Serial.begin(9600);
SPI.begin();
mfrc522.PCD_Init();

// Prepare the key: 0xff 0xff 0xff 0xff 0xff 0xff
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}

}

//===============================================
void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
return;

// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
Serial.print(“Card UID:”);
kirimkePC(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
int tagNo =0;
byte sector = 1;
byte blockAddr = 4;
byte trailerBlock = 7;
byte status;
byte buffer[18];
byte size = sizeof(buffer);

char bufferchar[16];
byte sizechar = sizeof(bufferchar);

status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(“Authenticate failed: “);
return;
}

// Read block
Serial.print(“hasil baca blok = “); Serial.print(blockAddr);
Serial.println();

status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK)
{
Serial.print(“Read failed”);
return;
}

kirimkePC(buffer, 16); Serial.println();

//konversi buffer dari byte ke string
for(byte j=0;j<16;j++)
{
bufferchar[j]=buffer[j];
}

bufferchar[15]=0x00; // string adalah array char yg diakhiri NULL (0x00)

Serial.print(bufferchar);
Serial.println();

//compare string hasil baca dengan string di database
tagNo=0xff;
for(byte i=0;i<10;i++)
{
if(strcmp(bufferchar, databaseTAG[i]) == 0)
{
tagNo=i;
}
}

if(tagNo !=0xff) // TAG cocok
{
Serial.print(“kunci terbuka”);Serial.println();
Serial.print(“selamat datang : “);
Serial.print(Name[tagNo]);
Serial.println();
digitalWrite(led1, HIGH);
delay(100);
digitalWrite(pintu, HIGH);
delay(2000);
digitalWrite(led1, LOW);

}
else // TAG tdk cocok
{
digitalWrite(led2, HIGH);
delay(100);
digitalWrite(buzzer, HIGH);
delay(100);
Serial.print(“anda tak berhak masuk”);
Serial.println();
}

mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
} // end of main loop
//========================================================

void kirimkePC(byte *buffer, byte bufferSize)
{
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? ” 0″ : ” “);
Serial.print(buffer[i], HEX);
}
}

Membuat Display 4 baris 7 segment menggunakan MAX7221

Teory dasar bisa dibaca di https://pccontrol.wordpress.com/2011/09/15/pemrograman-display-7-segment-dengan-spi-max7221-max7219/

pada contoh ini menggunakan 7 segment  kecil < 1 inch dgn tegangan 5v.jika Anda ingin menggunakan 7 segmen dgn tegangan lebih dari 5 v ( 7 segment ukuran yg besar i inch,2 inch 3 inch dst) maka tinggalditambahkan penguat daya misal dgn transistor atau ic ULN2083 atau lainnya.

4baris7segment

koneksi

max7221serial

Kode program C dengan codevision

 

/*****************************************************
CodeWizardAVR V1.24.
Chip type : ATmega16
Clock frequency : 11.059200 MHz
*****************************************************/
// Standard Input/Output functions
#include <stdio.h>
#include <delay.h>
#include <spi.h>
#include <mega16.h>
//=========================

// SPI
#define PIN_SCK PORTB.7
#define PIN_MOSI PORTB.5
#define PIN_SS PORTB.4

#define ON 1
#define OFF 0

#define MAX7219_LOADa1 PORTB.4=1 //chip enable 1
#define MAX7219_LOADa0 PORTB.4=0 //chip enable 0
#define MAX7219_LOADb1 PORTB.3=1 //chip enable 1
#define MAX7219_LOADb0 PORTB.3=0 //chip enable 0
#define MAX7219_LOADc1 PORTB.2=1 //chip enable 1
#define MAX7219_LOADc0 PORTB.2=0 //chip enable 0
#define MAX7219_LOADd1 PORTB.1=1 //chip enable 1
#define MAX7219_LOADd0 PORTB.1=0 //chip enable 0

#define MAX7219_MODE_DECODE 0x09
#define MAX7219_MODE_INTENSITY 0x0A
#define MAX7219_MODE_SCAN_LIMIT 0x0B
#define MAX7219_MODE_POWER 0x0C
#define MAX7219_MODE_TEST 0x0F
#define MAX7219_MODE_NOOP 0x00

#define MAX7219_DIGIT0 0x01
#define MAX7219_DIGIT1 0x02
#define MAX7219_DIGIT2 0x03
#define MAX7219_DIGIT3 0x04
#define MAX7219_DIGIT4 0x05
#define MAX7219_CHAR_BLANK 0xF
#define MAX7219_CHAR_NEGATIVE 0xA
//================================
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

//void MAX7219_displayNumber(volatile long number);
void MAX7219_displayNumber(long number,char baris);
void MAX7219_clearDisplay(char baris);
//void MAX7219_writeData(char data_register, char data);
void MAX7219_writeData(char data_register, char data, char baris);
void spiSendByte (char databyte);

// USART Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index]=data;
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
};
};
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm(“cli”)
–rx_counter;
#asm(“sei”)
return data;
}
#pragma used-
#endif

// Declare your global variables here
char digitsInUse = 5;
void main(void)
{
// Declare your local variables here

int a,b,c,d,i;
// Input/Output Ports initialization
// Port A initialization
PORTA=0x00;
DDRA=0x00;

// Port B initialization
PORTB=0x00;
DDRB=0xff; // SCK MOSI CS/LOAD/SS

// Port C initialization
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: Off
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x90;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x47;

// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 86.400 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
//SPCR=0x53;
//SPSR=0x00;
// SPI Enable, Master mode
SPCR =0x53;
for(i=1;i<5;i++)
{
// Decode mode to “Font Code-B”
MAX7219_writeData(MAX7219_MODE_DECODE, 0xFF,i);
// Scan limit runs from 0.
MAX7219_writeData(MAX7219_MODE_SCAN_LIMIT, digitsInUse – 1,i);
MAX7219_writeData(MAX7219_MODE_INTENSITY, 8,i);
MAX7219_writeData(MAX7219_MODE_POWER, ON,i);
delay_ms(50);
}
//

// Global enable interrupts
#asm(“sei”)

a=12305;
b=11300;
c=11612;
d=b-c;
MAX7219_displayNumber(a,1);
MAX7219_displayNumber(b,2);
MAX7219_displayNumber(c,3);
MAX7219_displayNumber(d,4);

while (1)
{

i=i+1;

if(i==999)i=0;
};

}

//===============================================================================
//=========================
void spiSendByte (char databyte)
{
SPDR = databyte;
// Wait until transfer is complete
while (!(SPSR & (1 << 7)));
}

void MAX7219_writeData(char data_register, char data, char baris)
{
if(baris==1)
{
MAX7219_LOADa0;
// Send the register where the data will be stored
spiSendByte(data_register);
// Send the data to be stored
spiSendByte(data);
MAX7219_LOADa1;
}
if(baris==2)
{
MAX7219_LOADb0;
// Send the register where the data will be stored
spiSendByte(data_register);
// Send the data to be stored
spiSendByte(data);
MAX7219_LOADb1;
}
if(baris==3)
{
MAX7219_LOADc0;
// Send the register where the data will be stored
spiSendByte(data_register);
// Send the data to be stored
spiSendByte(data);
MAX7219_LOADc1;
}
if(baris==4)
{
MAX7219_LOADd0;
// Send the register where the data will be stored
spiSendByte(data_register);
// Send the data to be stored
spiSendByte(data);
MAX7219_LOADd1;
}

}

void MAX7219_clearDisplay(char baris)
{
char i;
i = digitsInUse;
// Loop until 0, but don’t run for zero
do {
// Set each display in use to blank
MAX7219_writeData(i, MAX7219_CHAR_BLANK,baris);
} while (–i);

}

void MAX7219_displayNumber(long number,char baris)
{
char negative = 0;
char i = 0;
if (number < 0) {
negative = 1;
number =number * -1; //rubah ke +
}
MAX7219_clearDisplay(baris);
// If number = 0, only show one zero then exit
if (number == 0) {
MAX7219_writeData(1, 0,baris);
return;
}
// Initialization to 0 required in this case,
// does not work without it. Not sure why.
// Loop until number is 0.
do {
MAX7219_writeData(++i, number % 10,baris);
// Actually divide by 10 now.
number /= 10;
} while (number);

// display the sign.
if (negative) {
MAX7219_writeData(i+1, MAX7219_CHAR_NEGATIVE,baris);
}
}

Membuat Interface Board Untuk Latihan Input-Output, komunikasi RS232 dan RS485

Selain kita belajar mikrokontroller  melalui simulasi sebaiknya kita juga mencobanya dalam dlm keadaan sebenarnya.karena ada beberapa karakteristik elictrical yg tidak masuk dalam parameter di simulator.

Kita akan membuat sebuah board Input output dan komunikasi yg bisa dikoneksi  oleh systim minimum yg ada di pasaran. berikut ini blok diagramnya:

blogdigram

Dari gambar diatas bagian yg akan kita buat adalh interface board , dengan interface sbb:

  • 4 buah output 9-50 V DC   (tergantung daya yg diberikan)
  • 1 input sensor NPN standar industri (12/24v DC)
  • Komunikasi RS485
  • Komunikasi RS232

baiklah langsung saja kita buat rangkaian pada IDE eagle  sbb:

interfacesircuit

tambahkan rangkaian RS232

rs232circuit

setelah selesai circuit dibuat kita menuju board

Atur ukuran PCB dan tata letak komponen diboard sesuai kebutuhan Anda. kalau saya buatnya sbb:

interfaceboard

Interface Board  dengan ukuran 62mm  x 101mm ,sy buat ukuran tersebut untuk menyesuaikan dgn Casing yg tersedia yg sy punya.

casingboxlatihan

Dimensi Casing Almunium : tingggi 16cm (160mm), lebar 10cm (100mm) tinggi casing bagian dalamsekitar 5cm(50mm). dan ketebalan plat almunium sekitar 2,5mm

Berikut ini penampakan interface board yang sudah jadi :

interfaceboard

Penjelasan Masing masing bagian/fungsi dalam interface board:

  1. Dip Switch   ,  digunakan untuk input data  digital   dan  kombinasi dari dip switch bisa digunakan untuk alamat  pada percobaan komunikasi RS485. dipswitch
  2. Komunikasi RS485  digunakan untuk komunikasi ke banyak microcontroller.rs485circuite
  3. Output Penguat Daya ULN2803  bisa digunakan menggerakan device  yg mempunyai tegangan 6-50v. uln2083circuite
  4. Input  dgn Opto Coupler  , untuk dihubungkan ke sensor industri  atau juga switch on off. optocircuite
  5. Komunikasi RS232  digunakan untuk komunikasi ke PCrs232circuit

tobe continue….

 

 

Contoh Code C Microcontroller AVR Membaca String Barcode Scanner

/*****************************************************
Date : 7/27/2015
Chip type : ATmega16
Clock frequency : 11.059200 MHz
*****************************************************/

#include <mega16.h>
#include <delay.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#asm
//.equ __lcd_port=0x15 ;PORTC
//.equ __lcd_port=0x15 ;PORTC
.equ __lcd_port=0x1B ;PORTA
#endasm
#include <lcd.h>
#define PANJANGBARCODE 10

char barislcd=0;
unsigned int REGISTERS[50];
unsigned char data_in[15];
unsigned char databaca[15];
unsigned char data_count;
unsigned char ada_data;
unsigned int QtyOutput;
char lcd[25];
unsigned char indexarray=0;
char temdataArray[10][11];
//char balasan[]=”C=250″;
// Variables to hold current settings

void simpandiarray( char data[],unsigned char indek);
void bacaarray(char data[], char indek);
void process_command();
void simpankeregister(char strData[], unsigned char tempAddr) ;
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
data_in[data_count] = UDR;

// End of line!
if (data_in[data_count] == ‘\r’) // end of frame: ‘\n’ ‘\r’
{
data_in[data_count-1]=0x00; //data_in[] dijadikan string tambah 0x00 di akhir

if(data_count==12)
{
process_command() ;
}
else {
lcd_gotoxy(0,2);
lcd_putsf(“data eror “);
}
//clear_data_in();
data_count = 0;
return;
}
else
{
data_count++;
}
//============

}
// USART Transmitter buffer
#define TX_BUFFER_SIZE 8
char tx_buffer[TX_BUFFER_SIZE];
unsigned char tx_index,tx_counter;
// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (tx_counter)
{
–tx_counter;
UDR=tx_buffer[tx_index];
if (++tx_index ==8) tx_index=0;
};
}
void process_command()
{
char i,j,k,m;
//a b c d e f g h i j
//0 1 2 3 4 5 6 7 8 9
QtyOutput++ ;
delay_ms(50);
lcd_gotoxy(13,3);
itoa(QtyOutput,lcd);
lcd_puts(lcd);

simpandiarray(data_in,indexarray) ;

//display
bacaarray(databaca,indexarray);

lcd_gotoxy(0,barislcd);
lcd_puts(databaca);
delay_ms(50);
if(barislcd == 0){
lcd_gotoxy(11,barislcd+3);
lcd_putchar(0x20);
}
//=======================
if(barislcd > 0){
lcd_gotoxy(11,barislcd-1);
lcd_putchar(0x20);
}
lcd_gotoxy(11,barislcd);
lcd_putsf(“*”);
delay_ms(50);
//=======================

barislcd++;
if(barislcd==4) {
barislcd=0;
}

delay_ms(50);
lcd_gotoxy(13,2);
itoa(indexarray*5,lcd);
lcd_puts(lcd);

if(indexarray==9) {
indexarray=0;
lcd_gotoxy(13,2);
lcd_putchar(0x20);
lcd_gotoxy(14,2);
lcd_putchar(0x20);
lcd_gotoxy(13,2);
itoa(indexarray*5,lcd);
lcd_puts(lcd);
lcd_puts(lcd);
}
indexarray++;

}

void simpandiarray( char data[], unsigned char indek)
{
char i;
{
for(i=0;i<PANJANGBARCODE;i++)
temdataArray[indek,i]= data[i];
}
data[10]=0x00;
simpankeregister(data,(PANJANGBARCODE/2)*indek); // alamat 0,5,10,15,20

}

void bacaarray(char data[], char indek)
{
char i;
for(i=0;i<PANJANGBARCODE;i++){
data[i] =temdataArray[indek,i];
}
data[10]=0x00;
}
void main(void)
{

PORTA=0x00;
DDRA=0x00;

PORTB=0x00;
DDRB=0xff;

PORTC=0x00;
DDRC=0x00;

PORTD=0x37; //0011 0111
DDRD=0xc8; //1100 1000

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0xD8;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x47; //9600
//UBRRL=0x0B; //57600
//UBRRL=0x05; // 115200
PORTD.3=0;
// LCD module initialization
lcd_init(16);

lcd_gotoxy(0,0);
lcd_putsf(“barcode buffer”);
delay_ms(1000);
lcd_clear();
// Global enable interrupts
#asm(“sei”)

while (1)
{

}
}
//=============function declaration ==========================

//simpan 1 string barcode ke 5 register ab cd ef gh ij
void simpankeregister(char strData[],unsigned char tempAddr)
{
char i;
unsigned int tempData=0;

for(i=0;i<PANJANGBARCODE/2;i++,tempAddr++)
{
tempData = strData[(i*2)];
tempData = tempData <<8;
tempData = tempData | strData[i*2+1]; //
REGISTERS[tempAddr] = tempData;
}
}

Pengetahuan Dasar Pemrograman Sensor Berat ( Load Cell)

UNDER CONTRUCTION

Pendahulian

Sensor->IC HX711 -> Microcontroller -> Display

Sensor

Salah satu sensor berat (load cell ) yaitu Strain Gauge

Rangkaian Brigdge Stone

rangkaian ini digunakan untuk menambah sensitifitas output sensor

Serial Interface IC  HX711

IC HX711  adalah IC ADC 24 bit dgn output serial digital ,keluaran IC ini  berupa tegangan yg sebanding dengan berat yg di berikan.

HX711_OUT

Mencari peramaan linierisasi input Vs Output   (pers Y= aX + C).

karena input dan output tdk 100% linier maka perlu dicari persamaan untuk linierisasi hubungan input vs output.

Ambil data percobaan  berat dan Output Sensor

masukan tabel input vs output ke excel ->blok data tsb-> buat grafik scatter->klik kanan data di grafik -> add trenline->check add equationon chart.

misal  kita dapat persamaan Y=m.X – c    ,   Y adalah output ADC ,m =gradient/kemiringan ,  X = berat beban  , c =konstanta/offset

maka rumus mencari berat X = (Y-c)/m

code program membaca serial data IC HX711

misal dari beberapa data yg kita ambil kita dapatkan hubungan peramaan Y=0.5 X-600

Maka X= (Y-600)/0.5

 

#define  pin_data PORTB.0

#define pin_clock PORTB.1
unsigned long ReadCount(void){
unsigned long Count;
unsigned char i;

unigned long HX711_Buffer = 0;
unsigned long Weight= 0;
pin_data=1;
pin_clock=0;
Count=0;
while(pin_data);
for (i=0;i<24;i++){
pin_clock=1;
Count=Count<<1;
pin_clock=0;
if(pin_data) Count++;
}
pin_clock=1;
Count=Count^0x800000;
pin_clock=0;
return(Count);
}

unsigned int  GetWeight()
{
HX711_Buffer = ReadCount();
HX711_Buffer = HX711_Buffer/100;

Weight = HX711_Buffer;
Weight = Weight – 600;
Weight = (unsigned int)((float)Weight/0.5);

return Weight;
}

void main(void)

{

PORTB=0x01;
DDRB=0x02;

while(1)

{

// output ADC ic hx711 = readCount();

//berat=GetWeight();

}

referensi:

-datasheet HX711

-https://www.transducertechniques.com/wheatstone-bridge.aspx

-https://learn.sparkfun.com/tutorials/getting-started-with-load-cells

Contoh Program C# Menyimpan Data string di Slave Modbus RTU

Seperti kita ketahui bahwa type data yg dipakai dlm Modbus RTU,  master atau slave adalah integer.namun  seringkali kita membutuhkan menyimpan data dalambentuk string / ascii . untuk ini kita bisa mensiasati memperlakukan string/ kode  ascii sebagai integer.

modbus_string

Gambar 1.  Contoh sebuah Slave Modbus RTU  yg menerima/menyimpan “data string”

Untuk jelasnya langsung saja kita lihat contoh program di PC sebagai Master modbus yg akan menulis string berupa 8 buah kode ascii   ke modbus slave.

1.Buatlah project C# baru

2. buat form dan isi dengan objek  textBoxt  ganti namamenjadi txtDataString  dan Buton menjadi btnSimpan spt pada gambar dibawah ini

datastring

isikan kode berikut ini

private void btnSimpan_Click(object sender, EventArgs e)
{
int i,j,tambahanchar;
byte address = 1; // alamat slave yg akan ditulis

ushort[] value = new ushort[4];

if (txtDataString.Text.Length < 8) // tambahkan space
{
tambahanchar = 8 – txtDataString.Text.Length;
for (j = 0; j < tambahanchar; j++)
txtDataString.Text =txtDataString.Text + ” “;

}

if (txtDataString.Text.Length > 8) // potong string
{
MessageBox.Show(“batas max 8 huruf”);
txtDataString.Text = txtDataString.Text.Substring(0, 8);
}

this.Convertstrtohex();

for (i = 0; i < 4; i++)
value[i] = Convert.ToUInt16(datasend[i]);

if (mb.Open(lstPorts.SelectedItem.ToString(), Convert.ToInt32(lstBaudrate.SelectedItem.ToString()),
8, Parity.None, StopBits.One))
{
try
{

if (ModbusObjek.SendFc16(address, 8, (ushort)4, value)) ;   // modbus fungsi 16 menyimpan data ke beberapa register
{
lbstatus.Text = “berhasil ditulis”;
}

}
catch (Exception err)
{
lbstatus.Text =”gagal ditulis”;
}
}

mb.Close();
}

private void Convertstrtohex()
{ //BUAT ARRAY STRING HEXA
// AB CD EF GH
//4142 4344 4546 4748
// 0 4 8 12
// 0 1 2 3
string hexResult, SubstringResult, nilairegister;
hexResult = this.ConvertToHex(txtDataString.Text).ToString();
SubstringResult = hexResult.Substring(0, 4);
nilairegister = (int.Parse(SubstringResult, System.Globalization.NumberStyles.HexNumber)).ToString();

for (int i = 0; i < 4; i++)
{

datasend[i] = (int.Parse(hexResult.Substring(i * 4, 4), System.Globalization.NumberStyles.HexNumber)).ToString();

}

}

public string ConvertToHex(string asciiString)
{
string hex = “”;
foreach (char c in asciiString)
{
int tmp = c;
hex = hex + String.Format(“{0:x2}”, (uint)System.Convert.ToUInt32(tmp.ToString()));
}
return hex;
}

Menampilkan data register   dlm bentuk string pada arduino 

setelah  arduino menerima data ascii  dalam bentuk hex ,maka untuk menampilkan kita harus merubah data hex tersebut menjadi ascii   .

berikut ini contoh mudah merubah data 4 buah register menjadi string   sebanyak 8 karakter yg disimpan di variable array  namaModelDariPc .   1 register dirubah menjadi 2 karater.

seperti kita ketahui ,  string adalah array yg berakhiran NULL .

void printNamaModel(int regAwal)
{
namaModelDariPc[0] =(Mb.MbData[regAwal] & 0xff00)>>8;
namaModelDariPc[1] = Mb.MbData[regAwal] & 0x00ff;
namaModelDariPc[2] = (Mb.MbData[regAwal+1] & 0xff00)>>8;
namaModelDariPc[3] = Mb.MbData[regAwal+1] & 0x00ff;
namaModelDariPc[4] =(Mb.MbData[regAwal+2] & 0xff00)>>8;
namaModelDariPc[5] = Mb.MbData[regAwal+2] & 0x00ff;
namaModelDariPc[6] = (Mb.MbData[regAwal+3] & 0xff00)>>8;
namaModelDariPc[7] = Mb.MbData[regAwal+3] & 0x00ff;
namaModelDariPc[8] = 0x00;

Serial.print(namaModelDariPc);
}

 

Kesimpulan

Modbus RTU tetap tidak bisa  menyimpan data kode ascii  secara langsung. contoh diatas adalah merubah tiap kode ascii dari sebuah string menjadi type integer.

Contoh Dasar Pemrograman Kalkulator dengan microcontroller AVR C Codevision dgn simulasi proteus

Berikut ini contoh Program Kalkulator untuk Operasi aritmetik sederhana antara operand1 dan operand 2 hasil = operand1  operator  operand2 Operator yg digunakan :  X(kali), / (bagi), + (tambah), dan  – (kurang) Contoh  operasi aritmatik :   hasil = 34 X 2 keterangan: 34 adalah operand1 X adalah operator 2 adalah operand2 Rangkaian Simulasi dengan Proteus Calcisis Flowchart Program avrcalc Ringkasan Program

/*****************************************************
CodeWizardAVR V1.24.8d Professional
Chip type : ATmega16
*****************************************************/
#include &lt;mega16.h&gt;
#include &amp;amp;lt;delay.h&amp;amp;gt;
#include &amp;amp;lt;lcd.h&amp;amp;gt;
#include &amp;amp;lt;stdlib.h&amp;amp;gt;
#include &amp;amp;lt;math.h&amp;amp;gt;
#define scanKeypad 1
#define stopScan 0

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
#include &amp;amp;lt;lcd.h&amp;amp;gt;

int bacaKeyPad(void);
float kalkulator(void);

int operand1 = 0 , operand2 = 0 ;
float hasil = 0 ;
char kode=0 , bufferLCD[50] ;

void main(void)
{

PORTA=0x00;
DDRA=0x0F;

PORTC=0x00;
DDRC=0x00;

lcd_init(20);
while (1)
{
kalkulator();
};
}

//==================
int bacaKeyPad(void){
char StatusBaca = scanKeypad ;
while(StatusBaca==scanKeypad){

PORTA.0 = 1 ;
PORTA.1 = 0 ;
PORTA.2 = 0 ;
PORTA.3 = 0 ;
if(PINA.4 == 1){return 7 ; StatusBaca = stopScan;}
if(PINA.5 == 1){return 8 ; StatusBaca = stopScan;}
if(PINA.6 == 1){return 9 ; StatusBaca = stopScan;}
if(PINA.7 == 1){return 10; StatusBaca = stopScan;}
//==========================================
PORTA.0 = 0 ;
PORTA.1 = 1 ;
PORTA.2 = 0 ;
PORTA.3 = 0 ;
if(PINA.4 == 1){return 4 ; StatusBaca = stopScan;}
if(PINA.5 == 1){return 5 ; StatusBaca = stopScan;}
if(PINA.6 == 1){return 6 ; StatusBaca = stopScan;}
if(PINA.7 == 1){return 11; StatusBaca = stopScan;}
//==========================================
PORTA.0 = 0 ;
PORTA.1 = 0 ;
PORTA.2 = 1 ;
PORTA.3 = 0 ;
if(PINA.4 == 1){return 1 ; StatusBaca = stopScan;}
if(PINA.5 == 1){return 2 ; StatusBaca = stopScan;}
if(PINA.6 == 1){return 3 ; StatusBaca = stopScan;}
if(PINA.7 == 1){return 12; StatusBaca = stopScan;}
//==========================================
PORTA.0 = 0 ;
PORTA.1 = 0 ;
PORTA.2 = 0 ;
PORTA.3 = 1 ;
if(PINA.4 == 1){return 15; StatusBaca = stopScan;}
if(PINA.5 == 1){return 0 ; StatusBaca = stopScan;}
if(PINA.6 == 1){return 14; StatusBaca = stopScan;}
if(PINA.7 == 1){return 13; StatusBaca = stopScan;}
StatusBaca = scanKeypad ;
}
}
//==========================
float kalkulator(void)
{
int StatusBaca = scanKeypad ;
kode = bacaKeyPad();
if( kode &amp;amp;lt; 10 ) // kalau angka 0-9 ditekan
{
operand1 = (operand1*10)+ kode ;

itoa(kode , bufferLCD);                    // rubah kode ke ASCII
lcd_puts(bufferLCD);                      //tampilkan kode  operand1 yg ditekan
delay_ms(50);
}
//==========================
if( kode &amp;amp;gt; 9 &amp;amp;amp;&amp;amp;amp; kode &amp;amp;lt; 16 ) // jika ditekan 10,11,12,13,14,15 (X, -, +, atau /)
{

if(kode == 10)lcd_putchar('/') ;
if(kode == 11)lcd_putchar('X') ;
if(kode == 12)lcd_putchar('-') ;
if(kode == 13)lcd_putchar('+') ;
operator = kode;                      // simpan operator yg dipilih

{
kode = bacaKeyPad();

if( kode &amp;amp;lt; 10 )
{
operand2 = (operand2*10)+kode ;

itoa(kode , bufferLCD);                    // rubah kode ke  ASCII
lcd_puts(bufferLCD);                        //tampilkan kode  operand2 yg ditekan
delay_ms(50);

}
else if(kode == 14) //jika ditekan &amp;quot;=&amp;quot; laksanakan operasi
{
lcd_putchar('=');

if(operator == 10){ // jika ditekan '/'
hasil = operand1 / operand2 ;
}
if(operator == 11){ // jika ditekan 'X'
hasil = operand1 * operand2 ;
}
if(operator == 12){ // jika ditekan '-'
hasil = operand1 - operand2 ;
}
if(operator == 13){ // jika ditekan '+'
hasil = operand1 + operand2 ;
}

ftoa(hasil , 1 , bufferLCD);                // rubah hasil ke string ( string adalah array berisi ascii diakhiri NULL )
lcd_puts(bufferLCD);                         // print hasil ke LCD
delay_ms(100);
kode = 0 ;
StatusBaca = stopScan ;
}
}
}
//==============================

return 0;
}

Perbaikan kesalahan tampilan kode  pada tulisan diatas error

Berikut ini foto hasil dari kode kalkulator sederhana  diatas  yg di terapkan pada microcontroller AVR board.

kalkulator_avr

Contoh Pemrograman Dasar Keypad 4×4 untuk Menu Input Data Angka 4 digit

Hardware
– PC/Laptop
– Board Microcontroller AVR dgn RS232 Port
– Keypad 4×4
– USB to rs232 Converter
– Cable pita isi 10  female to female
– power suply untuk board microcontroller

Software
– Codevision
– Hyperterminal

Penjelasan

Pada Contoh berikut  setiap penekanan  dari Keypad akan di tampilkan pada Led di PORTC dan data angka 4 digit akan dikirim ke PC melalui serial Port.

Gambar :

menukeyboard1

koneksi header  PortA dan  Keypad 4X4

headerkeypad4x4

Gambar Hyperterminal Pada PC

menuhyperterminal

Ringkasan code proggramnya spt ini :

while (1)
{
keypad();

if(kode !=0xff)             // jika keypad ditekan
{
if(digit==4)                //input digit menu pilihan (1~4)
if(menu==1) digit--
else if(menu==2) digit--
else if(menu==3) digit--
else if(menu==4) digit--
else                       // "pilihlah menu"
else if(digit==3) digit-- // masukan input ribuan
else if(digit==2) digit-- // masukan input satuan
else if(digit==1) digit-- // masukan input puluhan
else if(digit==0) digit=4 // masukan input satuan

kode =0xff ;   // kembalikan kode ke 0ff setiap 1 digit angka diketik (tombol dilepas)
}

} end of while

Code Program Selengkapnya:

/*****************************************************
CodeWizardAVR V1.24.8d
Chip type : ATmega16
Clock frequency : 11.059200 MHz

*****************************************************/
#include  &lt; mega8535.h &gt;
#include &lt;stdio.h &gt;
#include &lt;stdlib.h&gt;
#include &lt;delay.h&gt;
#define waktuTekanTombol 500



// Declare your global variables here
unsigned char menu,digit=4;
unsigned int ribuan,ratusan,puluhan,satuan,hasil;
char kode ;
void keypad(void);
void origin(void);
void LED_kelap_kelip(char jml_looping, unsigned int waktu_delay);
void LED_berjalan(unsigned int waktu_delay);

void main(void)
{

// Port A initialization untuk KEYPAD 4X4
// PA.0-PA3 sbg input,,  PA4-PA&amp; sebagai Output
PORTA=0xFF;
DDRA=0xF0;

// Port B initialization
PORTB=0x00;
DDRB=0xF0;

// Port C initialization

//PORTC=0xFF;
//DDRC=0xF0;
PORTC=0x00;
DDRC=0xFF;

// Port D initialization
PORTD=0x00;
DDRD=0xB0;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity, Baud rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x47;

kode =0xff ;
LED_kelap_kelip(5,500);

while (1)
{

keypad();
if(kode !=0xff)
{

//================input data==========
if(digit==4) //menu pilihan
{
menu= kode;
//=======================================x
if(menu==1)
{

PORTC=menu;
putchar(48+kode);
delay_ms(waktuTekanTombol);
digit--;
putchar(13);
putchar(10);
}
else if(menu==2)
{

PORTC=menu;
putchar(48+kode) ;
delay_ms(waktuTekanTombol);
digit--;
putchar(13);
putchar(10);
}
else if(menu==3)
{

PORTC=menu;
putchar(48+kode);
delay_ms(waktuTekanTombol);
digit--;
putchar(13);
putchar(10);
}
else if(menu==4)
{

PORTC=menu;
putchar(48+kode);
delay_ms(waktuTekanTombol);
digit--;
putchar(13);
putchar(10);
}
else
{
LED_kelap_kelip(3,200);
}
//=======================================x

}
else if(digit==3) // masukan input ribuan
{
ribuan= kode;
PORTC = kode;
putchar(48+kode);
delay_ms(waktuTekanTombol);

digit--;
}
else if(digit==2)
{
ratusan = kode;
PORTC = kode ;
putchar(48+kode);
delay_ms(waktuTekanTombol);

digit--;
}
else if(digit==1)
{
puluhan = kode;
PORTC = kode;
putchar(48+kode);
delay_ms(waktuTekanTombol);

digit--;
}
else if(digit==0)
{
satuan = kode;
PORTC = kode ;
putchar(48+kode);
delay_ms(waktuTekanTombol);
putchar(10);
putchar(13);

putchar(48+menu);
putchar('@');
putchar(48+ribuan);//48+ribuan);
putchar(48+ratusan);//48+ribuan);
putchar(48+puluhan);//48+ribuan);
putchar(48+satuan);//48+ribuan);

LED_berjalan(1000);
origin();
delay_ms(waktuTekanTombol);

}

kode =0xff ; // kembalikan kode ke 0ff setiap 1 digit angka diketik (tombol tak ditekan)

} // penutup if(kode !=0xff)

} // end of while
} // end of main

&nbsp;
&nbsp;
//=================function definition==================
//=======================================================
void origin(void)
{ putchar(13);
putchar(10);
putchar('M');
putchar('e');
putchar('n');
putchar('u');
putchar('');
putchar('1');
putchar('-');
putchar('4');
putchar(':');
digit=4;
menu=0;
kode =0xff ;
ribuan=0;
ratusan=0;
puluhan=0;
satuan=0;
}

//============================================================
void keypad() //void untuk program keypad pada PORTA
{
PORTA.4=0;
delay_ms(3);
if (PINA.0==0) {kode=20;}
else if (PINA.1==0){kode=-13;}
else if (PINA.2==0){kode=0;}
else if (PINA.3==0){kode=-6;}

PORTA.4=1;
PORTA.5=0;
delay_ms(3);
if (PINA.0==0) {kode=19;}
else if (PINA.1==0){kode=9;}
else if (PINA.2==0){kode=8;}
else if (PINA.3==0){kode=7;}

PORTA.5=1; PORTA.6=0;
delay_ms(3);
if (PINA.0==0) {kode=18;}
else if (PINA.1==0){kode=6;}
else if (PINA.2==0){kode=5;}
else if (PINA.3==0){kode=4;}

PORTA.6=1; PORTA.7=0;
delay_ms(3);
if (PINA.0==0) {kode=17;}
else if (PINA.1==0){kode=3;}
else if (PINA.2==0){kode=2;}
else if (PINA.3==0){kode=1;}

PORTA.7=1;
delay_ms(3);
}

//============================================
void LED_kelap_kelip(char jml_looping, unsigned int waktu_delay)
{
char i;

PORTC=255;
for(i =0;i&lt;jml_looping;i++)
{
PORTC =~PORTC;

delay_ms(waktu_delay);
}

PORTC=255;

}
//============================================

void LED_berjalan(unsigned int waktu_delay)
{
char i,data;
PORTC=255;
delay_ms(waktu_delay);
PORTC=254;
delay_ms(waktu_delay);
PORTC=253;

//255-254-253-251-247-239-223-191-127
for(i=0; i&lt;7;i++)
{

PORTC=255-2^i;

delay_ms(waktu_delay);
}

PORTC=255;

}

Contoh Master Modbus dengan Bascom AVR

berikut ini contoh master  modbus RTU  dengan menggunakan bascom avr
compiler bascom avr  menyediakan fungsi library untuk master modbus yaitu “modbus.lbx” dan fungsi  untuk mengirim query modbus :

MAKEMODBUS(alamat slave, fucntion code, alamat register, varbts )

function code yg tersedia

  • 03 : read register

contoh

Slave Address                11
Function code                 03
alamat awal reg MSB    00
alamat awal reg  LSB      6B
jumlah reg MSB               00
jumlah reg LSB              03
CRC

  • 06 : write single register
  • 16 : write multiple register

$regfile = “m162def.dat”
$crystal = 8000000
$baud = 19200
$hwstack = 42
$swstack = 40
$framesize = 40

$lib “modbus.lbx”
Config Print1 = Portb.1 , Mode = Set

Rs485dir Alias Portb.1
Config Rs485dir = Output
Rs485dir = 0

Portc.0 = 1

‘The circuit from the help is used. See Using MAX485
‘ PB.1 data direction rs485

Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Com2 = 9600 , Synchrone = 0 , Parity = Even , Stopbits = 1 , Databits = 8 , Clockpol = 0

Open “COM2:” For Binary As #1

Dim B As Byte
Dim W As Word
Dim L As Long

W = &H4567
L = &H12345678

Print “RS-485 MODBUS master”
Do
If Pinc.0 = 0 Then
Waitms 500
Print “send request to slave/server”
‘ Send one of the following three messages
‘ Print #1 , Makemodbus(2 , 3 , 8 , 2);
‘ Print #1 , Makemodbus(2 , 6 , 8 , W);
Print #1 , Makemodbus(2 , 16 , 8 , L);
End If
If Ischarwaiting(#1) <> 0 Then
B = Waitkey(#1)
Print Hex(b) ; “,”;
End If
Loop

End

sumber

http://avrhelp.mcselec.com/index.html?modbus_slaveserver.htm

Contoh pemrograman AVR dgn sensor SHT11

Gambar Sckematik

konekasi sht11 dgn AVR

 

Program AVR

/*********************************************

Project : The Sensirion SHT11 Humidity & Temperature Demo
Chip type : AT90S8535

Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 192

SHT1X Humidity and Temperature Sensor
AVR
Pin 1 GND
Pin 2 Data (PB0)
Pin 3 Serial Clock (PB1)
Pin 4 VDD (2.4V to 5.5V)

AVR PB2 – Heater On/Off Switch

Pin PB2 high – Heater On
Pin PB2 low – Heater Off

*********************************************/

#include <90s8535.h>
#include <stdio.h>
#include <delay.h>
#include <math.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x1B
#endasm
#include <lcd.h>

// Declare your global variables here

typedef union
{ unsigned int i; float f;} value;

enum {TEMP,HUMI};

sfrb PINB = 0x16;
sfrb PORTB = 0x18;
sfrb DDRB = 0x17;

#define SHT_DATA_OUT DDRB.0
#define SHT_DATA_IN PINB.0
#define SHT_SCK PORTB.1
#define HEAT_SW PINB.2 // Heater On or Off
#define noACK 0
#define ACK 1
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0

const float C1=-4.0; // for 12 Bit
const float C2=+0.0405; // for 12 Bit
const float C3=-0.0000028; // for 12 Bit
const float T1=+0.01; // for 14 Bit @ 5V
const float T2=+0.00008; // for 14 Bit @ 5V

typedef struct{
unsigned char second; //enter the current time, date, month, and year
unsigned char minute;
unsigned char hour;
unsigned char date;
unsigned char month;
unsigned int year;
}time;
time t;

char lcd_buffer[33];

// Function Prototypes
interrupt [TIM2_OVF] void timer2_ovf_isr(void);
char not_leap(void);

//SHT Functions
char SHT_WriteByte(unsigned char value);
char SHT_ReadByte(unsigned char ack);
void s_transstart(void);
void s_connectionreset(void);
char s_softreset(void);
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);
void calc_sth11(float *p_humidity ,float *p_temperature);
float calc_dewpoint(float h,float t);

char s_write_statusreg(unsigned char *p_value);
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum);

void main(void)
{
// Declare your local variables here

value humi_val, temp_val;
unsigned char error, checksum, status;
float dew_point;

t.hour = 23;
t.minute = 30;
t.second = 00;
t.date = 22;
t.month = 8;
t.year = 2003;

// Input/Output Ports initialization
// Port A initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=Out Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=0 State6=T State7=T
PORTD=0x00;
DDRD=0x20;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: TOSC1 pin
// Clock value: PCK2/128
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x08;
TCCR2=0x05;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x40;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;

// LCD module initialization
lcd_init(20);
lcd_putsf(“- SHT11 Monitor -“);
//sprintf(lcd_buffer,”No. of Visitors = %d”,visitor);
//lcd_gotoxy(0,2);
//lcd_puts(lcd_buffer);

// Setup Sensibus Pins

PORTB.1 = 0; // ClockLow
DDRB.1 = 1; // SCK is an output

PORTB.0 = 0; // Always Zero
// Toggle DDRB.0 for Data

s_connectionreset();

/*
while (1)
{
s_transstart(); //transmission start

error+=SHT_WriteByte(MEASURE_TEMP); //send command to sensor

for (i=0;i<65535;i++)
if(SHT_DATA_IN==0) break; //wait until sensor has finished the measurement

if(SHT_DATA_IN) error+=1; //or timeout (~2 sec.) is reached

MSB =SHT_ReadByte(ACK); //read the first byte (MSB)
LSB =SHT_ReadByte(ACK); //read the second byte (LSB)
checksum =SHT_ReadByte(noACK); //read checksum

sprintf(lcd_buffer,”T= %u %u %u”,MSB,LSB,checksum);
lcd_gotoxy(0,1);
lcd_puts(lcd_buffer);

delay_ms(500);
}
*/

while (1)
{
error=0;
// Check heater pin
if(HEAT_SW)
status = 0b00000100; // Heater On
else status = 0b00000000; // Heater Off
s_write_statusreg(&status);

error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);
error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);
if(error!=0) s_connectionreset();
else{
humi_val.f=(float)humi_val.i; //converts integer to float
temp_val.f=(float)temp_val.i; //converts integer to float
calc_sth11(&humi_val.f,&temp_val.f); //calculate humidity, temperature
dew_point=calc_dewpoint(humi_val.f,temp_val.f); //calculate dew point
sprintf(lcd_buffer,”T:%5.1fC H:%5.1f%%”,temp_val.f,humi_val.f);
lcd_gotoxy(0,1);
lcd_puts(lcd_buffer);
if (HEAT_SW)
sprintf(lcd_buffer,”DP:%5.1fC Heat On “,dew_point);
else sprintf(lcd_buffer,”DP:%5.1fC Heat Off “,dew_point);
lcd_gotoxy(0,2);
lcd_puts(lcd_buffer);
}
// Global enable interrupts
#asm(“sei”)
delay_ms(1000);
#asm(“cli”)
}

}

// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// Place your code here
if (++t.second==60) //keep track of time, date, month, and year
{
t.second=0;
if (++t.minute==60)
{
t.minute=0;
if (++t.hour==24)
{
t.hour=0;
if (++t.date==32)
{
t.month++;
t.date=1;
}
else if (t.date==31)
{
if ((t.month==4) || (t.month==6) || (t.month==9) || (t.month==11))
{
t.month++;
t.date=1;
}
}
else if (t.date==30)
{
if(t.month==2)
{
t.month++;
t.date=1;
}
}
else if (t.date==29)
{
if((t.month==2) && (not_leap()))
{
t.month++;
t.date=1;
}
}
if (t.month==13)
{
t.month=1;
t.year++;
}
}
}
}
sprintf(lcd_buffer,”%02d:%02d:%02d %02d/%02d/%04d”,t.hour, t.minute, t.second, t.date, t.month, t.year);
lcd_gotoxy(0,3);
lcd_puts(lcd_buffer);
}

char not_leap(void) //check for leap year
{
if (!(t.year%100))
return (char)(t.year%400);
else
return (char)(t.year%4);
}
//———————————————————————————-
// writes a byte on the Sensibus and checks the acknowledge
//———————————————————————————-
char SHT_WriteByte(unsigned char value)
{
unsigned char i,error=0;
for (i=0x80;i>0;i/=2) //shift bit for masking
{
if (i & value) SHT_DATA_OUT=0; //masking value with i , write to SENSI-BUS
else SHT_DATA_OUT=1;
SHT_SCK=1; //clk for SENSI-BUS
delay_us(5); //pulswith approx. 5 us
SHT_SCK=0;
}
SHT_DATA_OUT=0; //release DATA-line
SHT_SCK=1; //clk #9 for ack
error=SHT_DATA_IN; //check ack (DATA will be pulled down by SHT11)
SHT_SCK=0;
return error; //error=1 in case of no acknowledge
}

//———————————————————————————-
// reads a byte form the Sensibus and gives an acknowledge in case of “ack=1”
//———————————————————————————-
char SHT_ReadByte(unsigned char ack)
{
unsigned char i,val=0;
SHT_DATA_OUT=0; //release DATA-line
for (i=0x80;i>0;i/=2) //shift bit for masking
{
SHT_SCK=1; //clk for SENSI-BUS
if (SHT_DATA_IN) val=(val | i); //read bit
SHT_SCK=0;
}
SHT_DATA_OUT=ack; //in case of “ack==1” pull down DATA-Line
SHT_SCK=1; //clk #9 for ack
delay_us(5); //pulswith approx. 5 us
SHT_SCK=0;
SHT_DATA_OUT=0; //release DATA-line
return val;
}

//———————————————————————————-
// generates a transmission start
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
//———————————————————————————-
void s_transstart(void)
{
SHT_DATA_OUT=0;
SHT_SCK=0; //Initial state
delay_us(1);
SHT_SCK=1;
delay_us(1);
SHT_DATA_OUT=1;
delay_us(1);
SHT_SCK=0;
delay_us(5);
SHT_SCK=1;
delay_us(1);
SHT_DATA_OUT=0;
delay_us(1);
SHT_SCK=0;
}

//———————————————————————————-
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
//———————————————————————————-

void s_connectionreset(void)
{
unsigned char i;
SHT_DATA_OUT=0; SHT_SCK=0; //Initial state
for(i=0;i<9;i++) //9 SCK cycles
{
SHT_SCK=1;
delay_us(1);
SHT_SCK=0;
}
s_transstart(); //transmission start
}

//———————————————————————————-
// resets the sensor by a softreset
//———————————————————————————-

char s_softreset(void)
{
unsigned char error=0;
s_connectionreset(); //reset communication
error+=SHT_WriteByte(RESET); //send RESET-command to sensor
return error; //error=1 in case of no response form the sensor
}

//———————————————————————————-
// makes a measurement (humidity/temperature) with checksum
//———————————————————————————-
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
unsigned error=0;
unsigned int i;

s_transstart(); //transmission start
switch(mode){ //send command to sensor
case TEMP : error+=SHT_WriteByte(MEASURE_TEMP); break;
case HUMI : error+=SHT_WriteByte(MEASURE_HUMI); break;
default : break;
}
for (i=0;i<65535;i++) if(SHT_DATA_IN==0) break; //wait until sensor has finished the measurement
if(SHT_DATA_IN) error+=1; // or timeout (~2 sec.) is reached
*(p_value+1) =SHT_ReadByte(ACK); //read the first byte (MSB)
*(p_value) =SHT_ReadByte(ACK); //read the second byte (LSB)
*p_checksum =SHT_ReadByte(noACK); //read checksum
return error;
}

//—————————————————————————————-
// calculates temperature [°C] and humidity [%RH]
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [%RH]
// temp [°C]
//—————————————————————————————-

void calc_sth11(float *p_humidity ,float *p_temperature)
{

//float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
//float t=*p_temperature; // t: Temperature [Ticks] 14 Bit
float rh_lin; // rh_lin: Humidity linear
float rh_true; // rh_true: Temperature compensated humidity
float t_C; // t_C : Temperature [°C]

t_C=*p_temperature*0.01 – 40; //calc. temperature from ticks to [°C]
rh_lin=C3*(*p_humidity)*(*p_humidity) + C2*(*p_humidity) + C1; //calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*(*p_humidity))+rh_lin; //calc. temperature compensated humidity [%RH]
if(rh_true>100)rh_true=100; //cut if the value is outside of
if(rh_true<0.1)rh_true=0.1; //the physical possible range

*p_temperature=t_C; //return temperature [°C]
*p_humidity=rh_true; //return humidity[%RH]
}

//——————————————————————–
// calculates dew point
// input: humidity [%RH], temperature [°C]
// output: dew point [°C]
//——————————————————————–

float calc_dewpoint(float h,float t)
{
float logEx,dew_point;
logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
dew_point = (logEx – 0.66077)*237.3/(0.66077+7.5-logEx);
return dew_point;
}

//———————————————————————————-
// reads the status register with checksum (8-bit)
//———————————————————————————-
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
{
unsigned char error=0;
s_transstart(); //transmission start
error=SHT_WriteByte(STATUS_REG_R); //send command to sensor
*p_value=SHT_ReadByte(ACK); //read status register (8-bit)
*p_checksum=SHT_ReadByte(noACK); //read checksum (8-bit)
return error; //error=1 in case of no response form the sensor
}

//———————————————————————————-
// writes the status register with checksum (8-bit)
//———————————————————————————-
char s_write_statusreg(unsigned char *p_value)
{
unsigned char error=0;
s_transstart(); //transmission start
error+=SHT_WriteByte(STATUS_REG_W);//send command to sensor
error+=SHT_WriteByte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}