PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   PIC - Thiết kế và Ứng dụng (http://www.picvietnam.com/forum/forumdisplay.php?f=23)
-   -   Đồng hồ + Đo nhiệt độ => LCD Ai quan tâm thì zô nhé (http://www.picvietnam.com/forum/showthread.php?t=1143)

zero 24-05-2007 10:32 PM

Đồng hồ + Đo nhiệt độ => LCD Ai quan tâm thì zô nhé
 
Mình định làm một bộ bao gồm việc đo nhiệt độ, đồng hồ có lịch âm dương, báo thức, báo chuông có kết nối với máy tính và mọi thông tin được hiển thị ra LCD.
Về cơ bản thì các công việc này ko khó khăn j cả nếu ta hiểu và nắm vững về ĐK. Với những j tôi biết để đầu tư cho một hệ thống này ước chừng phải bỏ ra > 200K cho tiền linh kiện cơ bản và chưa tính đến hỏng hóc. Nếu bạn nào biết cách nào đó để giảm bớt chi phí thì post lên cho tui với nhé
Hệ thống tôi định dùng các IC sau làm chủ yếu
Pic 16F877
DS 12C887
LM35
LCD 16x2

Vì 16F877 có chân AD nên ko cần dùng AD.
Còn việc giao tiếp với LCD thì đã có nhiều bài nói đến rồi
tiếp đến là cách kết nối với 12C887

Còn mạch nguyên lý và code mình xin dành lại cho các thành viên của diễn đàn.
Hi vọng anh em sẽ cùng hợp sức lại để làm một sản phẩm ngon, bổ, rẻ.

thaithienanh 25-05-2007 01:14 AM

:confused: cái này nhắc tới là mình tức ơi là tức hồi đó mình có làm một cái chạy tất nhiên là tạm thui, mình để đó ngắm chơi được nửa tháng, tự nhiên trong một ngày "đẹp trời thơ mộng" mình thức giấc nhìn vào LCD thấy một hàng ô đen thui mình nghĩ rùi chắc là mình phải "chia tay" một trong hai "em yêu" LCD hoặc PIC (kết quả là em PIC "đã xa anh") :( , mình tức quá dùng PIC khác nạp lại code gắn vào lại chạy tốt nhưng thấy ghê quá nên dẹp "bọn ác" qua một bên luôn, hic chả hiểu vì sao "em xa anh" luôn :confused:

zero 25-05-2007 10:35 AM

1 Attachment(s)
Chuyện chết bất đắc kỳ tử thì ko có j cả :D đồ china là vậy đó hihi
Quan trọng là mình làm được theo như những j mình đề ra hay ko thôi.
Vậy bạn đã làm được những j rồi?có thể chia xẻ lên được ko?
----------------------------------------
Mất một ngày để tìm trên NET cách connect DS12C887 với PIC nhưng ko thành công nên tôi thử viết Soucre để thực hiện việc kết nối với con này xem thế nào.(Nếu ai biết cách connect thì share cho tui với)

Theo như trong DataSheet thì quá trình đọc và ghi dữ liệu được thể hiện thông qua giản đồ thời gian.
Tôi mạo nguội đưa ra cách lập trình để kết nối với con DS như sau.
Code:

(Quá trình ghi dữ liệu)
B1. RD, RW =>1 delay.
B2. ALE => 1, Out DATA1 ra
B3. CS => 0
B4. Delay rồi cho ALE => 0 Delay
B5. RW => 0 và out DATA2 ra
B6. RW => 1 Delay
B7. CS => 1, ALE => 1.

Có vẻ khó hiểu nhỉ. vậy tôi sẽ minh họa bằng hình ảnh nhé.
Trong đó Data1 có thể là Address và Data2 là giá trị (Đoán vậy :D ko biết có đúng ko)
Còn với việc đọc Data thì cũng tương tự như vậy.
Ko biết có chính xác ko các bạn cho ý kiến nhé.

Có một đoạn nhầm lẫn trong ảnh là ở B3 CS=0 chứ ko phải là 1

nambkctk46 25-05-2007 02:04 PM

Mình cũng đã làm như vậy rùi, OK luôn. Chạy mấy tháng nay rùi ma vẫn chưa xỉu. Bác zero cứ tự tin mà làm đi.
Chúc thành công!

zero 25-05-2007 09:10 PM

vậy à.
thế bác làm như thế nào? dùng VĐK j? mà dùng chuẩn kết nối của nó hay viết code như trên.Có thể sharre cho tui được ko? có j nhắn theo YM nhé

huybo02 27-05-2007 12:48 PM

Em cũng muốn làm 1 cái như vậy nhưng làm sao để tính lịch âm dương?? DS12C887 làm được không? trong datasheet không thấy nói> Mong mọi người giúp

zero 27-05-2007 01:25 PM

DS ko làm được.
Muốn tính lịch âm dương thì cần sử dụng thuật toán để chuyển.
Đây là thuật toán dùng VB để đổi
Các bạn nghiên cứu thử nhé!

Code:

Private Can(10), Chi(12)
Function jdFromDate(dd, mm, yy)
Dim a, y, M, jd
a = Int((14 - mm) / 12)
y = yy + 4800 - a
M = mm + 12 * a - 3
jd = dd + Int((153 * M + 2) / 5) + 365 * y + Int(y / 4) - Int(y / 100) + Int(y / 400) - 32045
If (jd < 2299161) Then
    jd = dd + Int((153 * M + 2) / 5) + 365 * y + Int(y / 4) - 32083
End If
jdFromDate = jd
End Function

Function getNewMoonDay(k, timeZone)
Dim T, T2, T3, dr, Jd1, M, Mpr, F, C1, deltat, JdNew
T = k / 1236.85 '' Time in Julian centuries from 1900 January 0.5
T2 = T * T
T3 = T2 * T
dr = PI / 180
Jd1 = 2415020.75933 + 29.53058868 * k + 0.0001178 * T2 - 0.000000155 * T3
Jd1 = Jd1 + 0.00033 * Math.Sin((166.56 + 132.87 * T - 0.009173 * T2) * dr) ' Mean new moon
M = 359.2242 + 29.10535608 * k - 0.0000333 * T2 - 0.00000347 * T3 ' Sun's mean anomaly
Mpr = 306.0253 + 385.81691806 * k + 0.0107306 * T2 + 0.00001236 * T3 ' Moon's mean anomaly
F = 21.2964 + 390.67050646 * k - 0.0016528 * T2 - 0.00000239 * T3 ' Moon's argument of latitude
C1 = (0.1734 - 0.000393 * T) * Math.Sin(M * dr) + 0.0021 * Math.Sin(2 * dr * M)
C1 = C1 - 0.4068 * Math.Sin(Mpr * dr) + 0.0161 * Math.Sin(dr * 2 * Mpr)
C1 = C1 - 0.0004 * Math.Sin(dr * 3 * Mpr)
C1 = C1 + 0.0104 * Math.Sin(dr * 2 * F) - 0.0051 * Math.Sin(dr * (M + Mpr))
C1 = C1 - 0.0074 * Math.Sin(dr * (M - Mpr)) + 0.0004 * Math.Sin(dr * (2 * F + M))
C1 = C1 - 0.0004 * Math.Sin(dr * (2 * F - M)) - 0.0006 * Math.Sin(dr * (2 * F + Mpr))
C1 = C1 + 0.001 * Math.Sin(dr * (2 * F - Mpr)) + 0.0005 * Math.Sin(dr * (2 * Mpr + M))
If (T < -11) Then
    deltat = 0.001 + 0.000839 * T + 0.0002261 * T2 - 0.00000845 * T3 - 0.000000081 * T * T3
Else
    deltat = -0.000278 + 0.000265 * T + 0.000262 * T2
End If
JdNew = Jd1 + C1 - deltat
getNewMoonDay = Int(JdNew + 0.5 + timeZone / 24)
End Function

Function getSunLongitude(jdn, timeZone)

Dim T, T2, dr, M, L0, DL, L
PI = 3.14
T = (jdn - 2451545.5 - timeZone / 24) / 36525 ' Time in Julian centuries from 2000-01-01 12:00:00 GMT
T2 = T * T
dr = PI / 180 ' degree to radian
M = 357.5291 + 35999.0503 * T - 0.0001559 * T2 - 0.00000048 * T * T2 ' mean anomaly, degree
L0 = 280.46645 + 36000.76983 * T + 0.0003032 * T2 ' mean longitude, degree
DL = (1.9146 - 0.004817 * T - 0.000014 * T2) * Math.Sin(dr * M)
DL = DL + (0.019993 - 0.000101 * T) * Math.Sin(dr * 2 * M) + 0.00029 * Math.Sin(dr * 3 * M)
L = L0 + DL ' true longitude, degree
L = L * dr
L = L - PI * 2 * (Int(L / (PI * 2))) ' Normalize to (0, 2*PI)
getSunLongitude = Int(L / PI * 6)
End Function

Function getLunarMonth11(yy, timeZone)
Dim k, off, nm, sunLong
off = jdFromDate(31, 12, yy) - 2415021
k = Int(off / 29.530588853)
nm = getNewMoonDay(k, timeZone)
sunLong = getSunLongitude(nm, timeZone) ' sun longitude at local midnight
If (sunLong >= 9) Then
    nm = getNewMoonDay(k - 1, timeZone)
End If
getLunarMonth11 = nm
End Function

Function getLeapMonthOffset(a11, timeZone)

Dim k, Last, arc, i
k = Int((a11 - 2415021.07699869) / 29.530588853 + 0.5)
Last = 0
i = 1 ' We start with the month following lunar month 11
arc = getSunLongitude(getNewMoonDay(k + i, timeZone), timeZone)
While (arc <> Last And i < 14)
    Last = arc
    i = i + 1
    arc = getSunLongitude(getNewMoonDay(k + i, timeZone), timeZone)
Wend
getLeapMonthOffset = i - 1
End Function

Function convertSolar2Lunar(dd, mm, yy, timeZone)

Dim k, dayNumber, monthStart, a11, b11, lunarDay, lunarMonth, lunarYear, lunarLeap
dayNumber = jdFromDate(dd, mm, yy)
k = Int((dayNumber - 2415021.07699869) / 29.530588853)
monthStart = getNewMoonDay(k + 1, timeZone)
If (monthStart > dayNumber) Then
    monthStart = getNewMoonDay(k, timeZone)
End If
a11 = getLunarMonth11(yy, timeZone)
b11 = a11
If (a11 >= monthStart) Then
    lunarYear = yy
    a11 = getLunarMonth11(yy - 1, timeZone)
Else
    lunarYear = yy + 1
    b11 = getLunarMonth11(yy + 1, timeZone)
End If
lunarDay = dayNumber - monthStart + 1
diff = Int((monthStart - a11) / 29)
lunarLeap = 0
lunarMonth = diff + 11
If (b11 - a11 > 365) Then
    leapMonthDiff = getLeapMonthOffset(a11, timeZone)
    If (diff >= leapMonthDiff) Then
        lunarMonth = diff + 10
        If (diff = leapMonthDiff) Then
            lunarLeap = 1
        End If
    End If
End If
If (lunarMonth > 12) Then
    lunarMonth = lunarMonth - 12
End If
If (lunarMonth >= 11 And diff < 4) Then
    lunarYear = lunarYear - 1
End If
Text1.Text = lunarDay & "/" & lunarMonth & "/" & lunarYear
End Function

Private Sub Form_Load()
Can(1) = "Giap"
Can(2) = "At"
Can(3) = "Binh"
Can(4) = "Dinh"
Can(5) = "Mau"
Can(6) = "Ky"
Can(7) = "Canh"
Can(8) = "Tan"
Can(9) = "Nham"
Can(10) = "Quy"

Chi(1) = "Ty"
Chi(2) = "Suu"
Chi(3) = "Dan"
Chi(4) = "Mao"
Chi(5) = "Thin"
Chi(6) = "Ty"
Chi(7) = "Ngo"
Chi(8) = "Mui"
Chi(9) = "Than"
Chi(10) = "Dau"
Chi(11) = "Tuat"
Chi(12) = "Hoi"

timeZone = 7
convertSolar2Lunar 19, 5, 2007, 7
Me.Caption = Can((2007 + 6) Mod 10) & " " & Chi((2007 + 8) Mod 12)
End Sub


zero 29-05-2007 09:28 PM

Chán nhỉ chẳng có mấy người hào hứng với cái ứng dụng này.
Về cái mạch kết nối với con 12C887 thì tôi chưa có thời gian nghiên cứu được. Nhưng tôi sẽ Post phần dùng mạch đo nhiệt độ.
Vì mạch này tôi chỉ đưa ra để test cho mọi người thấy nên chưa quan tâm đến bố trí và tối ưu về cách sử dụng chân.
Dùng Port B để nối đến 8 Led báo (Hiển thị Giá trị đo được)
Kết nối con LM35:
1 => VDD
2 => PA0 (AN0) số 2
3 => VSS

Dùng một biến trở 10K mắc vào chân số 5 (RA3 Vref) chỉnh điện áp khoảng 2,5V
Code:

#include <16F877A.h>
#DEVICE ADC=8
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=12000000)
void main() {
  int i, value, min, max;
  setup_adc_ports(ALL_ANALOG);
  setup_adc( ADC_CLOCK_INTERNAL );
  set_adc_channel(0);
  set_tris_b(0);
while(1){
        value = Read_ADC();
        delay_ms(800);//Lâu lâu một tý để nhìn xem thấy nó có nhẩy giá trị lên ko
        output_b(value);
  }
}

Nếu bạn ko dùng hàm Delay_ms(800) thì cần đọc cờ ngắt ADC để đảm bảo quá trình chuyển đổi hoàn tất.
Lần sau có dịp tôi sẽ post chương trình cải tiến sử dụng INT_ADC để báo trạng thái chuyển đổi AD

Mecha 30-05-2007 07:46 AM

"Mình định làm một bộ bao gồm việc đo nhiệt độ, đồng hồ có lịch âm dương, báo thức, báo chuông có kết nối với máy tính và mọi thông tin được hiển thị ra LCD"

Mình có góp ý là: trong thực tế ứng dụng này không nên đưa phần ghép nối với máy tính vào làm gì.
Về chi phí, chắc bạn không thể làm rẻ hơn bọn China được đâu. Minh thấy ngay ở Hà Nội. một cài đồng hồ như thế này có mặt kính rất đẹp, giá cũng chỉ 200k chưa mặc cả :) Mua ở Lạng Sơn chắc chỉ 150k, qua biên giới chắc chỉ còn 100k. Không hiểu bọn China làm cách nào mà rẻ thế lol

huybo02 30-05-2007 12:16 PM

Phần đo nhiệt độ thì chỉ dùng ADC có sẵn trong PIC chỉ tốn 1 chân RA/AN thôi. Còn xuất ra thì có LCD rồi.
Cái này làm hồi mới tập tành ADC:

Code:

#include <16F877.h>
#device 16F877*=16 ADC=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=1000000)
#define use_portd_lcd TRUE
#include<lcd.c>
long adc,nhietdo;
long adc1,adc2,adc3,adc4,adc5,adc6,adc7,adc8,adc9,adc10,value;
int8 a,b,c,d;
void tachhang(int&a,int&b,int&c,int&d);
char so[11] ="0123456789";
void main()
{
setup_adc(adc_clock_internal);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_ms(100);

while(true)
{
  value = read_adc();
  /*adc1=read_adc();// doc 10 gia tri adc trong 1s
  delay_ms(100);
  adc2=read_adc();
  delay_ms(100);
  adc3=read_adc();
  delay_ms(100);
  adc4=read_adc();
  delay_ms(100);
  adc5=read_adc();
  delay_ms(100);
  adc6=read_adc();
  delay_ms(100);
  adc7=read_adc();
  delay_ms(100);
  adc8=read_adc();
  delay_ms(100);
  adc9=read_adc();
  delay_ms(100);
  adc10=read_adc();
  delay_ms(100);
  value =adc1+adc2+adc3+adc4+adc5+adc6+adc7+adc8+adc9+adc10;// lay gia tri trung binh adc*/
  nhietdo = (value-559)/0.2024;
  tachhang(a,b,c,d);
  lcd_init();
  delay_ms(100);
  lcd_putc(so[a]);
  lcd_putc(so[b]);
  lcd_putc(so[c]);
  lcd_putc('.');
  lcd_putc(so[d]);
}
}

void tachhang(int&a,int&b,int&c,int&d)
{
  a=nhietdo/1000;
  b=(nhietdo%1000)/100;
  c=(nhietdo%100)/10;
  d=nhietdo%10;
}


/* 5V = 1024 muc => 10mV tuong ung voi 2.048 muc ADC
0oC = 273oK => 0oC ung voi muc dien the 2.73V ung voi 559 muc ADC
Nhiet do = dien the Analog/10 - 273
Tuong ung
Nhiet do = (adc -559)/2.024
Xuat gia tri nhiet do ra LED 7 doan hay LCD*/

13% và 17% ROM hơi nhiều :(

giangcs 30-05-2007 09:26 PM

cho đệ hỏi hiển cái,đệ muốn hiện h lên LCD nhưng hiện ko đúng,đệ dùng 1307.Đệ đã đọc được dữ liệu ra máy tính.Huynh nào làm rồi cho đệ cái hàm chuyển đổi nhỉ.

zero 31-05-2007 11:31 PM

To Mecha: Việc kết nối với máy tính thì mình nghĩ là ko thêm chi phí đáng là bao nhiêu (1 cái Cáp LPT or COM)việc kết nối với máy tính có thể làm các việc sau.
Hẹn giờ báo => có chú thích và đổ chuông tùy ý (Kiểu như cái calenda của điện thoại) Cái LCD để làm gì? cốt là để làm cái này.
Cập nhật giờ từ máy tính để dễ dàng cho việc Config lại nếu có sai.
Đây là làm đơn chiếc thủ công và rất nhiều lý do khác nữa nên việc giá thành có thể cao hơn. Và còn lý do khác mà ta chưa biết.
Mình nghĩ so sánh cái đồng hồ của TQ thì cái của mình có rất nhiều lợi điểm đấy chứ và cũng có thể ứng dụng vào việc báo chuông định kỳ ...............
Hi vọng có người ủng hộ!

zero 31-05-2007 11:50 PM

Mà cái này làm cho vui thôi <= để cảm thấy hạnh phúc khi làm một sản phẩm nào đó để trong nhà. Với lại cái này cũng có thể đưa lên cao hơn chút để kinh doanh mà <= Làm hệ thống báo chuông ấy.
À tiện cho hỏi chút (Mecha) Trong 8051 có hỗ trợ giao tiếp với Ram ngoài theo chuẩn Intel vậy PIC có hỗ trợ ko?nếu có thì làm hay tìm tài liệu nào.
Em xem chuẩn giao tiếp PSP nhưng chỉ thấy nó dùgn 3 chân CS,RD,WR chứ ko thấy dùng chân ALE!

minhquan1910 01-06-2007 03:27 AM

sao cậu không dùng ds1307 ? kết nối i2c tiện lợi hơn nhiều chứ nhỉ ? tốn chỉ có 2 chân của Pic thôi .

zero 01-06-2007 09:23 PM

cũng có thể nhưng hiện tại mình chưa biết con 1307 như thế nào nếu ko cấp nguồn cho nó thì nó có chạy ko?
Nếu chỉ vì ko dùng được một con IC nào đó mà ta chuyển sang dùng cái khác thì thực sự đó ko phải là cách hay (Vì đây là nghiên cứu mà) tuy nhiên khi nào có dịp mình sẽ thử con 1307 xem sao. Mà giá của nó bao nhiêu ấy nhỉ ^^


Múi giờ GMT. Hiện tại là 12:31 PM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam