ช่วยดูให้ทีนะคับ
ว่าทำไมพอต่อใช้งานจริงแล้วมันสามารถ อินพุต portA ใช้ได้แค่ pinA0,A1,A2,A3 และทำไม Output แสดงผล ออกได้แค่ pin B0 ,Pin B3 อะคับ
ผมลองย้ายไป Pin B2,B4,B5,B6,B7,B8 ดูแล้ว แต่ output ไม่ออกอะคับ
ช่วยแนะนำทีคับ
ผมใช้ PIC เบอร์ 16f88 คับ
นี่เป็นโค็ดนะคับ
#include <16F88.h> // Standard Header file for the PIC16F877A
#device ADC = 10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#define vbe 0.0048875855327468230694037145650049 // Vref/1023 ;Vref = 5 volt
float ldr1,ldr2,ldr3,ldr4,vldr1,vldr2,vldr3,vldr4;
void main(void)
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);
while(TRUE)
{
set_adc_channel(0);
delay_us(10);
ldr1 = read_adc();
vldr1 = vbe * (float)ldr1;
if(vldr1>2)
{
output_high(PIN_B0);
}else{output_low(PIN_B0);}
//_______________________________________________________________
set_adc_channel(1);
delay_us(10);
ldr2 = read_adc();
vldr2 = vbe * (float)ldr2;
if(vldr2>2)
{
output_high(PIN_B1);
}else{output_low(PIN_B1);}
//______________________________________________________________
set_adc_channel(2);
delay_us(10);
ldr3 = read_adc();
vldr3 = vbe * (float)ldr3;
if(vldr3>2)
{
output_high(PIN_B2);
}else{output_low(PIN_B2);}
//_______________________________________________________________
set_adc_channel(3);
delay_us(10);
ldr4 = read_adc();
vldr4 = vbe * (float)ldr4;
if(vldr4>2)
{
output_high(PIN_B3);
}else{output_low(PIN_B3);}
}
}
ไม่มีใครตอบเลยอะ
Simulate แล้วก็ปกติดีนิครับ
แล้ววงจรที่ต่อหน่ะต่อยังไงครับ โพสให้ดูหน่อยได้ไหม
ปล.คุณตั้งกระทู้ซะดึกขนาดนี้ แล้วกะให้เขาตอบเลย คุณกะไม่ให้แอ็ดมินกับเพื่อนๆนอนเลยหรอครับ
ผมโพสมาหลายวันแล้วอะคับ
เอ่อตอนนี้แก้ไขในส่วนนี่ได้แล้วนะคับ มันเกิดจากบอร์ดที่สั่งมา มีจัมเปอร์เสียบอยู่ ทำให้ไม่สามารถใช้พอร์ตได้อะคับ
ขอบคุณมากนะคับที่ตอบ
เอ่ออีกเรื่องนึงนะคับ
ช่วยดูโค๊ดทีนะคับ
#include <16F88.h> // Standard Header file for the PIC16F877A
#device ADC = 10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#define vbe 0.0048875855327468230694037145650049 // Vref/1023 ;Vref = 5 volt
float infa1,vinfa1,infa2,vinfa2,infa3,vinfa3;
void main(void)
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);
while(TRUE)
{
//NUM 1
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
if (vinfa1<1){
delay_ms(1000);
output_low(PIN_B1);}
else if((vinfa1>=1.2)&&(vinfa1<=2 ))
{
output_high(PIN_B0);
delay_ms(4000);
output_low(PIN_B0);}
else{output_low(PIN_B0);}
// ------------------------------------------------------------------------
//NUM2
set_adc_channel(1);
delay_us(10);
infa2 = read_adc();
vinfa2 = vbe * (float)infa2;
if (vinfa2<1){
delay_ms(1000);
output_low(PIN_B1);}
else if((vinfa2>=1.2)&&(vinfa2<=2 ))
{
output_high(PIN_B1);
delay_ms(4000);
output_low(PIN_B1);}
else{output_low(PIN_B1);}
จาก CODE นี้นะคับ
คือว่าพอจะมีวิธีให้มันทำงานพร้อมกันมั้ยคับ
คือตอนนี้เนี่ยพอรับ Input เข้ามาทั้ง 2 อินพุต Output ที่ B0 ก็ทำงาน
แต่ว่า Outputที่ B1 ยังไม่ทำงานอะคับ มันต้องรอให้ Delay ที่ Output B0 ทำงานเร็จก่อน
Outputที่ B1 ถึงจะทำงานอะคับ
ผมต้องใช้interupt มั้ยคับ
แต่ว่าผม interupt ไม่เป็นอะคับ
อาจจะต้องให้ Interrupt ของ Timer 0 หรือ Timer 1 ครับ
Code การใช้ Interrupt ไม่ยากครับ แต่ว่าต้อง Setup Timer ในตัว CPU ให้ถูกครับ
ทำไม่เป็นอะคับผม
พี่พอจะช่วยได้มั้ยคับ
พอดีต้องส่งอาจารย์อะคับ
:'( :'(
แนวคิด
output_low(pin_b0);
output_low(pin_b1);
a=read_adc(0)*0.004888;
if(a>=1.2 && a<=2)
output_high(pin_b0);
a=read_adc(0)*0.004888;
if(a>=1.2 && a<=2)
output_high(pin_b1);
delay_ms(4000);
....................
มันอาจจะทำงานไม่ถึงกับเท่ากัน แต่ไกล้เคียง ถ้าอยากทำให้พร้อมกันก็ทำได้ ไม่ถึงกับ Interrupt หรอกครับ
เขียนแบบ state machine ครับ ง่ายสุดแล้ว โจทย์ว่ายังไงครับ ผมดูตรงเงื่อนไขแล้ว งงๆ
Quote from: ozuke on February 17, 2013, 01:35:10 PM
แนวคิด
output_low(pin_b0);
output_low(pin_b1);
a=read_adc(0)*0.004888;
if(a>=1.2 && a<=2)
output_high(pin_b0);
a=read_adc(0)*0.004888;
if(a>=1.2 && a<=2)
output_high(pin_b1);
delay_ms(4000);
....................
มันอาจจะทำงานไม่ถึงกับเท่ากัน แต่ไกล้เคียง ถ้าอยากทำให้พร้อมกันก็ทำได้ ไม่ถึงกับ Interrupt หรอกครับ
เอ่อ มัน Run ไม่ผ่านอะคับ
ติดที่ a=read_adc(0)*0.004888; อะคับ
Quote from: JENG on February 17, 2013, 01:45:26 PM
เขียนแบบ state machine ครับ ง่ายสุดแล้ว โจทย์ว่ายังไงครับ ผมดูตรงเงื่อนไขแล้ว งงๆ
ก็คือว่า
รับอินพุตเข้ามา 2 ตัว พร้อมกันแล้วให้ Output ทำงานพร้อมกันอะคับ
//NUM 1
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
if (vinfa1<1){
delay_ms(1000);
output_low(PIN_B1);}
else if((vinfa1>=1.2)&&(vinfa1<=2 ))
{
output_high(PIN_B0);
delay_ms(4000);
output_low(PIN_B0);}
else{output_low(PIN_B0);}
// ------------------------------------------------------------------------
//NUM2
set_adc_channel(1);
delay_us(10);
infa2 = read_adc();
vinfa2 = vbe * (float)infa2;
if (vinfa2<1){
delay_ms(1000);
output_low(PIN_B1);}
else if((vinfa2>=1.2)&&(vinfa2<=2 ))
{
output_high(PIN_B1);
delay_ms(4000);
output_low(PIN_B1);}
else{output_low(PIN_B1);}
จาก CODE คือว่า
คือผมจะเอาไปใช้ที่โถปัสสาวะชายอะคับ ให้น้ำราดเอง
คือเมื่อคนเข้ามา ระบบก็ยังไม่ทำงานก่อน
รอจนกว่าคนจะออกไปแล้วค่อยทำงาน แล้วหน่วงเวลาไว้ 4 วิ อะคับ
//NUM1
เมื่อรับ Input จากเซนเซอร์ทางขา A0 ถ้าน้อยกว่าระยะของเซนเซอร์น้อยกว่า 1 ก็หน่วงเวลา 1 วิ //คือตรงนี้เมื่อมีคนเดินเข้ามามันก็จะช่วยให้ระบบยังไม่ทำงาน
และเมื่อรับ Input จากเซนเซอร์ทางขา A0 ถ้าอยู่ในช่วง 1.2 -2 ก็ให้มันทำงาน และหน่วงเวลาไว้ 4 วิ //คือตรงนี้ในกรณีที่คนเดินออกไป แล้วราดน้ำอะคับ
ตอนนี้อะมันทำงานได้อะคับ
ในกรณีที่เข้ามาพร้อมกัน Output ตัวที่ 2 จะทำงานได้ก็ต้องให้ Output ตัวที่ 1 ทำงานเสร็จก่อน
มันยังแหม่งๆอยู่นะแต่เข้าใจแล้วล่ะว่าจะทำอะไร เดี๋ยวเย็นนี้กลับบ้านผมจะลองทำตัวอย่างให้ดู
Quote from: JENG on February 17, 2013, 02:42:36 PM
มันยังแหม่งๆอยู่นะแต่เข้าใจแล้วล่ะว่าจะทำอะไร เดี๋ยวเย็นนี้กลับบ้านผมจะลองทำตัวอย่างให้ดู
ขอบคุณมากนะคับผม
:) :) :) :)
รบกวนหน่อยแล้วนะคับ
ผมใช้บอร์ดของ ETT
ตัวนี้คับ
http://www.etteam.com/prod2010/PIC/PIC-et-base-pic16f628-v1.html (http://www.etteam.com/prod2010/PIC/PIC-et-base-pic16f628-v1.html)
และใช้ PIC16f88 คับ
Quote from: pomcoe on February 17, 2013, 02:08:35 PM
เอ่อ มัน Run ไม่ผ่านอะคับ
ติดที่ a=read_adc(0)*0.004888; อะคับ
มันคือแนวคิด ครับ ถ้าอยากให้รันได้ต้องอ่านแล้วทำความเข้าใจครับ
นี่แสดงว่าไม่ยอมอ่าน ไม่ยอมทำความเข้าใจรึปล่าว หรือมันไม่รู้เรื่องจริงๆ
ถ้าอ่านนิด ทำความเข้าใจหน่อยมันก็ทำได้แ้ล้วครับ
1.สั่ง LOW pin_b1,pin_b0
2.อ่าน adc 0 แล้วมาคำนวนเป็นโวลต์เก็บไว้ที่ตัวแปร a
2.1 ถ้า a มากกว่า 1.2 และน้อยกว่า 2 ให้ pin_b0 เป็น high
3.อ่าน adc 1 แล้วมาคำนวนเป็นโวลต์ เก็บไว้ที่ตัวแปร a
3.1 ถ้า a มากกว่า 1.2 และน้อยกว่า 2 ให้ ยin_b1 เป็น high
4.delay 4000 ms
5.กลับไปทำข้อ 1.
โชคดีครับ
ถ้าผมบอกมากกว่านี้ มันก็ไม่ต่างอะไรกันกับลอกการบ้านส่ง
ผมอยากให้คุณเข้าใจ มากกว่า การได้ส่งงานแบบไม่รู้เรื่อง
คิดว่าคงเข้าใจผมนะ
ผมตัดออกให้ดูง่ายๆนะไม่รู้ว่าตรงตามความต้องการหรือป่าว
คือเมื่อมีการตรวจจับสัญญานได้ว่า ((vinfa1>=1.2)&&(vinfa1<=2 ))
ผมสมมุติอยู่ใน Task2 ตัวแปร ADC_CH1,ADC_CH2;
ถ้าอยู่ใน RANGE ให้หน่วงก่อนทำงานเป็นเวลา 1 วินาที ถ้า ไม่อยู่
ใน RANGE เกิน 1 วินาที ให้ RESET Counter
ถ้าเกิน 1 วินาที ให้สั่งเปิด OUTPUT และจะมี TASK3 เป็นตัวจัดการปิด
OUTPUT โดยอัตโนมัติหลัง 4 วินาที พอมองออกมั๊ย
ผมมั่วๆเอาน่าจะพอเป็นแนวได้
unsigned char ADC_CH1,ADC_CH2;
//Tick
void Tick(void){
//set timer 10ms tick
}
//Task1
void Task1(void){
//read adc and calculat send to ADC_CH1,ADC_CH2;
}
//Task2
unsigned int RB0_CNT2,RB1_CNT2;
void Task2(void){
if(ADC_CH1){ //adc in range
if(RB0_CNT2++>=100){
RB0_CNT2 = 0;
RB0 = 1;
}
}else{
RB0_CNT2 = 0;
}
if(ADC_CH2){ //adc in range
if(RB1_CNT2++>=100){
RB1_CNT2 = 0;
RB1 = 1;
}
}else{
RB1_CNT2 = 0;
}
}
//Task3
unsigned int RB0_CNT3,RB1_CNT3;
void Task3(void){
if(RB0){
if(RB0_CNT3++>=400){
RB0_CNT3 = 0;
RB0 = 0;
}
}
if(RB1){
if(RB1_CNT3++>=400){
RB1_CNT3 = 0;
RB1 = 0;
}
}
}
//Main Program
int main(void){
for(;;){
Tick(); //tick 10ms
Task1(); //read adc and cal.
Task2(); //delay befor execute 1sec
Task3(); //auto turn off after 4sec
}
}
Quote from: ozuke on February 17, 2013, 03:54:21 PM
Quote from: pomcoe on February 17, 2013, 02:08:35 PM
เอ่อ มัน Run ไม่ผ่านอะคับ
ติดที่ a=read_adc(0)*0.004888; อะคับ
มันคือแนวคิด ครับ ถ้าอยากให้รันได้ต้องอ่านแล้วทำความเข้าใจครับ
นี่แสดงว่าไม่ยอมอ่าน ไม่ยอมทำความเข้าใจรึปล่าว หรือมันไม่รู้เรื่องจริงๆ
ถ้าอ่านนิด ทำความเข้าใจหน่อยมันก็ทำได้แ้ล้วครับ
1.สั่ง LOW pin_b1,pin_b0
2.อ่าน adc 0 แล้วมาคำนวนเป็นโวลต์เก็บไว้ที่ตัวแปร a
2.1 ถ้า a มากกว่า 1.2 และน้อยกว่า 2 ให้ pin_b0 เป็น high
3.อ่าน adc 1 แล้วมาคำนวนเป็นโวลต์ เก็บไว้ที่ตัวแปร a
3.1 ถ้า a มากกว่า 1.2 และน้อยกว่า 2 ให้ ยin_b1 เป็น high
4.delay 4000 ms
5.กลับไปทำข้อ 1.
โชคดีครับ
ถ้าผมบอกมากกว่านี้ มันก็ไม่ต่างอะไรกันกับลอกการบ้านส่ง
ผมอยากให้คุณเข้าใจ มากกว่า การได้ส่งงานแบบไม่รู้เรื่อง
คิดว่าคงเข้าใจผมนะ
ขอโทษนะคับผมรีบโพสต์เกินไป
คือว่าผมจะเอาไฟจาก 5V ไปติ๊กให้มีการหน่วงเวลา 5 วินาที ใครมีวงจร รบกวนหน่วยนะคับ
ขอบคุณมากคับ :) :)
ง่ายๆ ก็ 555
http://home.cogeco.ca/~rpaisley4/LM555.html#29
ขอรายละเอียดมากกว่านี้ได้ม๊ยครับอ่านแล้วยังไม่เข้าใจ เพราะถ้า trig เฉยๆ ก็ใช้ monostable 555 ก็ได้
Quote from: mviboolr on March 05, 2013, 09:43:07 AM
ขอรายละเอียดมากกว่านี้ได้ม๊ยครับอ่านแล้วยังไม่เข้าใจ เพราะถ้า trig เฉยๆ ก็ใช้ monostable 555 ก็ได้
เอ่อ ก็แค่จ่ายไฟ 5V ไปติ๊กทีนึง
แล้วสั่งให้หน่วงการทำงาน ประมาณ 5 วิอะคับ
ซึ่งไฟ output 5V จาก PIC อะคับที่ไปติ๊ก
ให้ PIC Tric & Delay 5 Sec. ได้มั้ยครับ :)
งง ครับ อะไรยังไง เหมือนว่า ต้องการสั่งงานจาก PIC หลังจากสั่งแล้ว ให้รออีก 5 วิ ถึงจะทำงานใช่รึป่าวครับ
ถ้ายังงั้น ทำไมไม่ให้ PIC รออีก 5 วิ แล้วค่อยสั่งล่ะ หรือ ผมเข้าใจอะไรผิด
Quote from: top on March 05, 2013, 12:35:55 PM
ให้ PIC Tric & Delay 5 Sec. ได้มั้ยครับ :)
เอ่อพอดีมันมีปัญหานิดนึงคับ
คือว่าผมรับอินพุตเข้ามา 3 ตัว แล้วต้องการให้แสดงผล output พร้อมกันทั้ง 3 ตัว น่ะคับ
แต่ว่ามันติดปัญหาตรงที่ Delay
คือว่า output ตัวที่ 2 จะทำงานได้มันต้องรอ output ตัวที่ 1 ให้ทำงานเสร็จก่อรน่ะคับ
ผมเองจึงเลือกที่จะแก้ไขปัญหาตรงที่ Hardware อะคับ
เพราะไม่ค่อยถนัด Program น่ะคับ อีกอย่างคือต้องรีบส่งด้วยคับ
พอจะมีวงจรบ้างมั้ยคับ ???
ใช้ 555 สามตัวแยกกันทำงานไง
น่าจะมี Timing Chart มาให้หน่อยนะ เพราะเท่าที่บอกมาอ่านแล้วงง เพราะเห็นบอกว่า
Quote
คือว่าผมรับอินพุตเข้ามา 3 ตัว แล้วต้องการให้แสดงผล output พร้อมกันทั้ง 3 ตัว น่ะคับ
แต่ว่ามันติดปัญหาตรงที่ Delay
คือว่า output ตัวที่ 2 จะทำงานได้มันต้องรอ output ตัวที่ 1 ให้ทำงานเสร็จก่อรน่ะคับ
แล้วจะ Delay ตรงไหน I/P หรือ O/P
ตอนนี้มี Code หรือ วงจร หรือ ลำดับการทำงานของเครื่อง อะไรสักอย่างไหมครับ :)
ขอดูหน่อย ( ได้ทั้งหมดเลยยี่งดีครับ ) :)
ขอหลักการทำงานด้วยครับ เช่น สถานะปกติ Sensor จะอ่านได้เท่าไหร่
เมื่อมีคนมา Sensor จะอ่านได้เท่าไหร่ และต้องการ ควบคุมยังไง
เท่าที่อ่านๆดู ผมตีความได้ประมาณนี้
float infa1,vinfa1,infa2,vinfa2,infa3,vinfa3;
unsigned int delay1, delay2, delay3;
void main(void)
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);
while(TRUE)
{
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
if((vinfa1>=1.2)&&(vinfa1<=2 ))
{
output_high(PIN_B0);
delay1 = 4000;
}
set_adc_channel(1);
delay_us(10);
infa2 = read_adc();
vinfa2 = vbe * (float)infa2;
if((vinfa2>=1.2)&&(vinfa2<=2 ))
{
output_high(PIN_B1);
delay2 = 4000;
}
set_adc_channel(2);
delay_us(10);
infa3 = read_adc();
vinfa3 = vbe * (float)infa3;
if((vinfa3>=1.2)&&(vinfa3<=2 ))
{
output_high(PIN_B2);
delay3 = 4000;
}
if( --delay1 == 0 ) output_low(PIN_B0);
if( --delay2 == 0 ) output_low(PIN_B1);
if( --delay3 == 0 ) output_low(PIN_B2);
delay_ms(1);
}
}
float infa1,vinfa1,infa2,vinfa2,infa3,vinfa3;
unsigned int delay1, delay2, delay3;
void main(void)
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);
while(TRUE)
{
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
if((vinfa1>=1.2)&&(vinfa1<=2 ))
{
output_high(PIN_B0);
delay1 = 4000;
}
set_adc_channel(1);
delay_us(10);
infa2 = read_adc();
vinfa2 = vbe * (float)infa2;
if((vinfa2>=1.2)&&(vinfa2<=2 ))
{
output_high(PIN_B1);
delay2 = 4000;
}
set_adc_channel(2);
delay_us(10);
infa3 = read_adc();
vinfa3 = vbe * (float)infa3;
if((vinfa3>=1.2)&&(vinfa3<=2 ))
{
output_high(PIN_B2);
delay3 = 4000;
}
if( --delay1 == 0 ) output_low(PIN_B0);
if( --delay2 == 0 ) output_low(PIN_B1);
if( --delay3 == 0 ) output_low(PIN_B2);
delay_ms(1);
}
}
Quote from: crywolf on March 06, 2013, 10:05:50 AM
float infa1,vinfa1,infa2,vinfa2,infa3,vinfa3;
unsigned int delay1, delay2, delay3;
void main(void)
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);
while(TRUE)
{
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
if((vinfa1>=1.2)&&(vinfa1<=2 ))
{
output_high(PIN_B0);
delay1 = 4000;
}
set_adc_channel(1);
delay_us(10);
infa2 = read_adc();
vinfa2 = vbe * (float)infa2;
if((vinfa2>=1.2)&&(vinfa2<=2 ))
{
output_high(PIN_B1);
delay2 = 4000;
}
set_adc_channel(2);
delay_us(10);
infa3 = read_adc();
vinfa3 = vbe * (float)infa3;
if((vinfa3>=1.2)&&(vinfa3<=2 ))
{
output_high(PIN_B2);
delay3 = 4000;
}
if( --delay1 == 0 ) output_low(PIN_B0);
if( --delay2 == 0 ) output_low(PIN_B1);
if( --delay3 == 0 ) output_low(PIN_B2);
delay_ms(1);
}
}
ขอบคุณมากนะคับ
เดี๋ยวจะลองทดสอบดูนะคับ เดี๋ยวจะมาบอกนะคับ :) :)
Quote from: top on March 05, 2013, 03:18:15 PM
ตอนนี้มี Code หรือ วงจร หรือ ลำดับการทำงานของเครื่อง อะไรสักอย่างไหมครับ :)
ขอดูหน่อย ( ได้ทั้งหมดเลยยี่งดีครับ ) :)
http://www.electoday.com/index.php?topic=310.0
อ่านกระทู้เก่าแล้ว ผมคิดว่าแก้ไข Code น่าจะง่ายกว่าใช้วงจรหน่วงเวลาเพราะว่า ในบางครั้งก็ฉีเสร็จแล้วแต่ยืนคุยกันอยู่ก็มี แล้วถ้ามันเกิน 4 หรือ 5 วิ เครื่องก็ทำงานเลยอยู่ดีนะครับ
เพิ่มเติมหรือถ้าไม่อย่างงั้นก็ ใช้ พวก PIC 12F675 ตัวล่ะ 35 บาท แยกช่องสัญญาณกันไปเลยดีกว่าไหม ก็ใช้ Code เดิม แค่เปลี่ยน Port ที่เป็น I/O บนตัวโปรแกรม ไม่ต้องรอให้ช่องอื่น ทำเสร็จก่อน ของใครของมันไปเลย ไม่ต้องต่อ X-Tal ด้วย เพราะมีอยู่ในตัว PIC12F675
Quote from: crywolf on March 06, 2013, 10:05:50 AM
float infa1,vinfa1,infa2,vinfa2,infa3,vinfa3;
unsigned int delay1, delay2, delay3;
void main(void)
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);
while(TRUE)
{
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
if((vinfa1>=1.2)&&(vinfa1<=2 ))
{
output_high(PIN_B0);
delay1 = 4000;
}
set_adc_channel(1);
delay_us(10);
infa2 = read_adc();
vinfa2 = vbe * (float)infa2;
if((vinfa2>=1.2)&&(vinfa2<=2 ))
{
output_high(PIN_B1);
delay2 = 4000;
}
set_adc_channel(2);
delay_us(10);
infa3 = read_adc();
vinfa3 = vbe * (float)infa3;
if((vinfa3>=1.2)&&(vinfa3<=2 ))
{
output_high(PIN_B2);
delay3 = 4000;
}
if( --delay1 == 0 ) output_low(PIN_B0);
if( --delay2 == 0 ) output_low(PIN_B1);
if( --delay3 == 0 ) output_low(PIN_B2);
delay_ms(1);
}
}
เอ่อมันก็ได้ยุนะคับ แต่ว่าพอลองต่อจิง
ดูเหมือนว่ าไม่ว่าเราจะกำหนดค่า delay เท่าไร มันก็ดูเหมือนว่าจะยังหน่วงเวลาเท่าเดิมคับ
Quote from: olee on March 06, 2013, 02:22:25 PM
เพิ่มเติมหรือถ้าไม่อย่างงั้นก็ ใช้ พวก PIC 12F675 ตัวล่ะ 35 บาท แยกช่องสัญญาณกันไปเลยดีกว่าไหม ก็ใช้ Code เดิม แค่เปลี่ยน Port ที่เป็น I/O บนตัวโปรแกรม ไม่ต้องรอให้ช่องอื่น ทำเสร็จก่อน ของใครของมันไปเลย ไม่ต้องต่อ X-Tal ด้วย เพราะมีอยู่ในตัว PIC12F675
คือแยกกันตัวต่อตัวเลยเหรอคับ
ใช่ครับ เพราะว่าคุณไม่สามารถเขียนโปรแกรมแบบแยก Task โดยใช้เวลาเป็นตัวกำหนดได้ งั้น แยก hardware เป็น 12F แยกตัวไปเลยจะง่ายกว่าสำหรับคุณ ซึ่งยังเขียนโปรแกรมไม่ค่อยคล่อง
Quote from: olee on March 06, 2013, 03:00:20 PM
ใช่ครับ เพราะว่าคุณไม่สามารถเขียนโปรแกรมแบบแยก Task โดยใช้เวลาเป็นตัวกำหนดได้ งั้น แยก hardware เป็น 12F แยกตัวไปเลยจะง่ายกว่าสำหรับคุณ ซึ่งยังเขียนโปรแกรมไม่ค่อยคล่อง
คับผม
ขอรายละเอียดหน่อยครับ
Sensor ทำงานยังไง ค่า 1.2V หรือ 2V เกิดขึ้นตอนใหน? และค่าอื่นๆที่มากกว่า หรือ น้อยกว่า เกิดขึ้นตอนใหน?
ต้องการให้มี Output ตอนใหน? เป็น Low หรือเป็น High และต้องการให้ เป็น Low กี่ วินาที เป็น high กี่ วินาที
ยิ่งมีรายละเอียดเยอะ คนที่มาช่วยก็จะช่วยได้เร็วขึ้น ช่วยได้ตรงจุด เท่าที่อ่านมา ผมยังไม่เข้าใจ ความต้องการของคุณเลย
Code ที่ให้ไปก็เกิดจากการเดาล้วนๆ
ถ้าในวงจรของคุณ มี 1 I/P(Sensor IR) และ 1 O/P(สำหรับ Solenoid) ก็ใช้ PIC 12F ได้เลย เพราะตัวที่ผมบอกไปมี a/d 10 bit อยู่แล้ว แล้วก็ ES มีขาย ที่เหลือคือ คุณมีตัวโปรแกรม หรือเปล่า เพราะถึงมีก็ต้องต่อวงจรอีกนิดหน่อย
โดยผมรับอินพุตมาจากอินฟาเรทเซนเซอร์อะคับ
แล้วเอาค่าการตรวจจับมาเป็นอินพุต ซึ่งจะเป็นค่า แรงดัน (vinfa)
ซึ่งผมต้องการให้ Input 3 ตัว Output 3 ตัว สามารถทำงานได้พร้อมกันเมื่อมีคนเข้ามาใช้งานพร้อมกัน
คือเมื่อคนเข้ามา ระบบก็ยังไม่ทำงานก่อน ( ตรงนี้ถ้าระยะยิ่งไกลค่าแรงดันก็จะ < 1 ตรงนี้ผมจึงให้หน่วงเวลาไว้ไม่ให้มันทำงาน 1 วินาที)
รอจนกว่าคนจะออกไปแล้วค่อยทำงาน แล้วหน่วงเวลาไว้ 4 วิ อะคับ ( ((vinfa1>=1.2)&&(vinfa1<=2 )) ก็คือถ้าค่าคนเดินมายังจุดนี้ ระยะการตรวจจับเท่านี้ ก็ให้ทำงาน )
//NUM1
เมื่อรับ Input จากเซนเซอร์ทางขา A0 ถ้าน้อยกว่าน้อยกว่า 1V ก็หน่วงเวลา 1 วิ //คือตรงนี้เมื่อมีคนเดินเข้ามามันก็จะช่วยให้ระบบยังไม่ทำงาน
และเมื่อรับ Input จากเซนเซอร์ทางขา A0 ถ้าอยู่ในช่วง 1.2 -2V ก็ให้มันทำงาน และหน่วงเวลาไว้ 4 วิ //คือตรงนี้ในกรณีที่คนเดินออกไป แล้วราดน้ำอะคับ
//NUM 1
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
if (vinfa1<1){
delay_ms(1000); //คนเข้ามาแล้วยังไม่ทำงานก่อน ให้หน่วงเวลา 1 วินาที
output_low(PIN_B0);}
else if((vinfa1>=1.2)&&(vinfa1<=2 )) //คนเดินออกไป แล้วตรงกับระยะนี้พอดี ก็สั่งให้ทำงานคับ
{
output_high(PIN_B0);
delay_ms(4000); //คนเดินออกไป ก็จะทำงาน โดยหน่วงเวลา 4 วินาที
output_low(PIN_B0);}
else{output_low(PIN_B0);}
เคยเห็นคนเมายืนฉี่เปล่า อาจจะทำให้ไม่เข้าเงื่อนไขที่คุณคิดก็ได้นะ
Quote from: olee on March 06, 2013, 03:49:39 PM
เคยเห็นคนเมายืนฉี่เปล่า อาจจะทำให้ไม่เข้าเงื่อนไขที่คุณคิดก็ได้นะ
โห ไม่หลอกคับ เป็นที่มหาลัยนะ
ถ้ามีก็อาจจะพลาดบ้างคับ
เข้ามา 100 คน ตรวจจับได้สัก 95 คน ก็ Okey แล้วคับ
นั้นแหละคับ มันคงไม่มีบอร์ดแบบสำเร็จรูป เพราะต้องใช้หลายตัวเลย
ผมล้อเล่น น่ะ ;D
บอกตรงๆๆนะ
ถ้าผมทำได้ ผมคงไม่เข้ามาขอความช่วยเหลือหลอก
ผมไม่ค่อยถนัดโปรแกรมจิงๆ
อิอิ
ก็ยังงงๆอยู่ดี
งั้นผมจะเขียนให้ตามที่เข้าใจนะ
#include <16F88.h> // Standard Header file for the PIC16F877A
#device ADC = 10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#define vbe 0.0048875855327468230694037145650049 // Vref/1023 ;Vref = 5 volt
unsigned int delay1,delay2,delay3,wait1,wait2,wait3;
float infa1,vinfa1,infa2,vinfa2,infa3,vinfa3;
void main(void)
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);
while(TRUE)
{
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
if((vinfa1>=1.2)&&(vinfa1<=2 ))
{
wait1 = 1000;
}
set_adc_channel(1);
delay_us(10);
infa2 = read_adc();
vinfa2 = vbe * (float)infa2;
if((vinfa2>=1.2)&&(vinfa2<=2 ))
{
wait2 = 1000;
}
set_adc_channel(2);
delay_us(10);
infa3 = read_adc();
vinfa3 = vbe * (float)infa3;
if((vinfa3>=1.2)&&(vinfa3<=2 ))
{
wait3 = 1000;
}
if( wait1 > 0 )
{
if( --wait1 == 0 )
{
output_high(PIN_B0);
delay1 = 4000;
}
}
if( wait2 > 0 )
{
if( --wait2 == 0 )
{
output_high(PIN_B1);
delay2= 4000;
}
}
if( wait3 > 0 )
{
if( --wait3 == 0 )
{
output_high(PIN_B2);
delay3 = 4000;
}
}
if( delay1 > 0 )
if( --delay1 == 0 ) output_low(PIN_B0);
if( delay2 > 0 )
if( --delay2 == 0 ) output_low(PIN_B1);
if( delay3 > 0 )
if( --delay3 == 0 ) output_low(PIN_B2);
delay_ms(1);
}
}
Quote from: crywolf on March 06, 2013, 06:26:29 PM
ก็ยังงงๆอยู่ดี
งั้นผมจะเขียนให้ตามที่เข้าใจนะ
#include <16F88.h> // Standard Header file for the PIC16F877A
#device ADC = 10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#define vbe 0.0048875855327468230694037145650049 // Vref/1023 ;Vref = 5 volt
unsigned int delay1,delay2,delay3,wait1,wait2,wait3;
float infa1,vinfa1,infa2,vinfa2,infa3,vinfa3;
void main(void)
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);
while(TRUE)
{
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
if((vinfa1>=1.2)&&(vinfa1<=2 ))
{
wait1 = 1000;
}
set_adc_channel(1);
delay_us(10);
infa2 = read_adc();
vinfa2 = vbe * (float)infa2;
if((vinfa2>=1.2)&&(vinfa2<=2 ))
{
wait2 = 1000;
}
set_adc_channel(2);
delay_us(10);
infa3 = read_adc();
vinfa3 = vbe * (float)infa3;
if((vinfa3>=1.2)&&(vinfa3<=2 ))
{
wait3 = 1000;
}
if( wait1 > 0 )
{
if( --wait1 == 0 )
{
output_high(PIN_B0);
delay1 = 4000;
}
}
if( wait2 > 0 )
{
if( --wait2 == 0 )
{
output_high(PIN_B1);
delay2= 4000;
}
}
if( wait3 > 0 )
{
if( --wait3 == 0 )
{
output_high(PIN_B2);
delay3 = 4000;
}
}
if( delay1 > 0 )
if( --delay1 == 0 ) output_low(PIN_B0);
if( delay2 > 0 )
if( --delay2 == 0 ) output_low(PIN_B1);
if( delay3 > 0 )
if( --delay3 == 0 ) output_low(PIN_B2);
delay_ms(1);
}
}
ขอบคุณมากนะคับที่ช่วยเหลือ
แต่ยังไม่ได้อะคับ
งั้นผมคงต้องใช้แบบ อินพุต ต่ออินพุต แล้วคับ
ขอบคุณมากนะคับ
ผมว่าส่วน sensor ออกแบบใหม่ดีกว่าครับอาจจะต่อกับ comparator ภายนอกแล้วปรับเอาหรือตามที่ทำอยู่ก็ได้ไม่ว่ากัน ;D
ส่วนการทำงานที่ถูกต้องเป็นดังนี้
1.หน่วงเวลาก่อนทำงาน 5 วินาทีขึ้นไป (รูดซิบแล้วฉี่เร็วกว่า5วิให้มันรู้ไป ;D ) กันในกรณีคนเดินผ่านแล้วทำงาน
2.ถ้าเกิน5วิให้ state เป็นรอการเปิดน้ำ (ถ้าไม่เกินก็ reset counter)
3.เมื่อstate รอเปิดน้ำแล้วให้ sensor คืนสถานะเดิมก่อน(ฉี่เสร็จแล้วเดินออก) ค่อยสั่งเปิดน้ำ 5วิแล้วหยุด
ถ้าจะทำแบบ chip เดียวคุมสามช่องเลยถ้าไม่มีความรู้ความชำนาญเรื่อง coding แบบ state machine
หรือมองภาพการทำงานแบบ state ไม่ออก ผมว่าเลี่ยงไปใช้ chip แยกกันทำงานดีกว่า
โชคดีครับ ;D
ผมว่าเรายังสับสน เราต้องการแบบนี้ใช่ไหม
1. Sensor 1 ตรวจได้ว่า มีคนอยู่
2. ตราบเท่าที่ SENSOR ยังจับได้ให้ เครื่องยังไม่นับหรือ Triger ทำงาน
3. เมื่อเครื่อง SENSOR จับไม่ได้ ก็เริ่ม Trig ให้ counter หน่วง ไป 4 SEC
4. หลังจากนั้น RELAY จะทำงานให้ Valve น้ำ จ่ายน้ำเพื่อล้างโถ เป็นเวลา 5 sec
5. Valve จะตัด เมื่อ ครบเวลา 5 sec
6. หากระหว่างที่ Valve น้ำเปิดอยู่ Sensor จะไม่ทำงาน เพื่อให้การจ่ายน้ำล้างโถให้เกลี้ยง
___|----------~~~~ ---------|_________________________|----------|________________________________ SENSOR 1
__________ ~~~~~______|-----5 sec-----|_____________________|-------5 Sec---|___________________ Triger
___________~~~~~~ ________________|----5 sec---|________________________|----5 SeC------|______ Relay Status
Hardware :
infrared reciever >|---------> A/D -----
infrared Transmitter <|-------- DO--------
RELAY <------------------------DO---------
LED STATUS 1 <---------------DO---------
LED STATUS 2 <----------------DO---------
POWER SUPPLY 220/5 V ISOLATE
Quote from: skytec on March 09, 2013, 12:29:37 AM
ผมว่าเรายังสับสน เราต้องการแบบนี้ใช่ไหม
1. Sensor 1 ตรวจได้ว่า มีคนอยู่
2. ตราบเท่าที่ SENSOR ยังจับได้ให้ เครื่องยังไม่นับหรือ Triger ทำงาน
3. เมื่อเครื่อง SENSOR จับไม่ได้ ก็เริ่ม Trig ให้ counter หน่วง ไป 4 SEC
4. หลังจากนั้น RELAY จะทำงานให้ Valve น้ำ จ่ายน้ำเพื่อล้างโถ เป็นเวลา 5 sec
5. Valve จะตัด เมื่อ ครบเวลา 5 sec
6. หากระหว่างที่ Valve น้ำเปิดอยู่ Sensor จะไม่ทำงาน เพื่อให้การจ่ายน้ำล้างโถให้เกลี้ยง
___|----------~~~~ ---------|_________________________|----------|________________________________ SENSOR 1
__________ ~~~~~______|-----5 sec-----|_____________________|-------5 Sec---|___________________ Triger
___________~~~~~~ ________________|----5 sec---|________________________|----5 SeC------|______ Relay Status
Hardware :
infrared reciever >|---------> A/D -----
infrared Transmitter <|-------- DO--------
RELAY <------------------------DO---------
LED STATUS 1 <---------------DO---------
LED STATUS 2 <----------------DO---------
POWER SUPPLY 220/5 V ISOLATE
ประมาณนั้นคับ
ขอบคุณมากนะคับที่ช่วย
แล้วทำได้ยังครับ
ตอนนี้อะวงจรได้แล้วคับ
แต่ถ้าได้โปรแกรมที่แยกการทำงานจะดีกว่าคับ
ทำเสร็จหรือยังครับ ;D
ทำเสร็จหรือยังครับ ;D
เกือบแระ 55 ;D ;D
ตอนนี้ได้แระคับ
แต่ว่ามันยังเพี้ยนๆๆ บ้างทีมันก็ติดเอง
ทำไงดีอะคับ
ที่คิดไว้คือ พอคนเข้ามาไม่ต้องทำงานก่อน
แต่พอคนออกไปจึงค่อยทำงาน
เขียนโปรแกรมไม่ถูก อิอิ
ช้อมูลของเราไม่เพียงพอที่จะช่วย หากอยากให้ช่วย เราต้องให้ข้อมูล มากกว่านี้ เช่น วงจร สิ่งที่เราต้องการ และอื่นๆ
นี่เป็นโค็ดเดิม
#include <16F88.h> // Standard Header file for the PIC16F877A
#device ADC = 10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#define vbe 0.0048875855327468230694037145650049 // Vref/1023 ;Vref = 5 volt
float infa1,vinfa1;
void start(int1 pin)
{
if(pin==0) output_high(PIN_B1);
else output_high(PIN_B2);
}
void stop(int1 pin)
{
if(pin==0) output_low(PIN_B1);
else output_low(PIN_B2);
}
void delay_1mingreen(void){
start(0);
delay_ms(500);
stop(0);
delay_ms(500);
}
void main(void)
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);
while(TRUE)
{
//NUM 1
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
output_high(PIN_B1); //led green on // คือตอนแรกให้แสดงสถานะไฟพร้อมทำงาน
if (vinfa1<0.6){ //ตรงนี้คนเดินเข้ามา แล้วหน่วงเวลาไม่ให้ทำงาน
delay_ms(6000); //delay 6 s.
output_low(PIN_B0); // solinoid valve off
}
else if (vinfa1>1.4){ //ตรงนี้พอคนเข้ามาแล้วได้ระยะ ก้ให้แสดงสถานะกำลังทำงาน
delay_1mingreen(); //led green blink
}
else if((vinfa1>=0.6)&&(vinfa1<=0.8 )) //ตรงนี้คนเดินออกไป แล้วตรงระยะ ก็เลยให้ทำงาน มันติดตรงนี้แหละถ้าเกิดเดิน ไม่ตรงระยะมันก็ไม่ทำงาน
{
//delay_ms(2000);
output_low(PIN_B1); //led green off
output_high(PIN_B2); // led red on
output_high(PIN_B0); // solinoid valve on
delay_ms(6000); //delay 6 s.
output_low(PIN_B0); // solinoid valve off
output_low(PIN_B2); // led red off
}
else{
output_low(PIN_B0); // solinoid valve off
output_high(PIN_B1); //led green on
reset_cpu();
}
}
}
โค็ดเดิมมีปัญหาตรงที่
บางทีก็ทำงานปรกติ
แต่บางทีก็ทำงานเองแบบ งง
แต่ตอนนี้เปลี่ยนใหม่แล้ว
คืออยากให้ พอคนเข้ามา แล้วตรงระยะที่อินฟาเรดเซนเซอร์ทำงาน ที่ 0.6 หรือมากกว่า ก็ยังไม่ต้องทำงานก่อน
แต่พอคนออกไปจึงค่อยทำงาน
จุดประสงค์คือ รับอินพุตมาจากอินฟาเรทเซนเซอร์
แล้วควบคุมการเปิด ปิด solinoid valve
เอาไปใช้กับโถปัสสาวะชายคับ
sensor ติดอยู่ตรงไหน
ด้านบนของโถฉี่จะมีที่วางคับ
http://www.sparkfun.com/datasheets/Components/GP2Y0A21YK.pdf (http://www.sparkfun.com/datasheets/Components/GP2Y0A21YK.pdf) รายล่ะเอียดเซนเซอร์คับ
ระยะที่เหมาะสมคือ ค่าโวล์ตทีออกจาก เซนเซอร์ ตั้งแต่ 0.6
---------- interrupt routine ทุกๆ 1 วินาที ----------
sampling adc
if 0.6<adc< 2 {
set input status
set counter
}
else {
clear input status
}
// end interrupt routine-----------------------------
------------------------ main -----------------------
if (input status == 1) && (counter ==2) { // ตรวจเจอคน
led on // ไฟแสดงสถานะ
}
if (input status == 0) && (5< counter < 10) { // ฉี่เสร็จเรียบร้อย
output on
delay
output off
led off
clear counter
}
else {
led off
clear counter
}
// end main ----------------------------------------
พอเป็นแนวคิด
น่าจะช่วยได้บ้างหากเข้าใจเรื่อง timer interrupt
Quote from: pomcoe on March 13, 2013, 08:59:45 PM
ตอนนี้ได้แระคับ
แต่ว่ามันยังเพี้ยนๆๆ บ้างทีมันก็ติดเอง
ทำไงดีอะคับ
การใช้งาน ADC ของ PIC ต้องทำ filter สัญญาณ input หน่อยก็ดีครับเพราะว่าบางครั้งสัญญาณที่อ่านได้มันไม่นิ่ง
น่ะครับมาจากหลายสาเหตุเช่นสัญญาณรบกวน อุณหภูมิก็มีผลกับระดับแรงดันที่อ่านเข้ามาได้ มันเลยทำให้ค่า ADC มีการแกว่งได้น่ะครับ
ได้แล้วคับ
ผมวน LOOP เอาง่ายๆๆเลย 55
;D ;D ;D ;D ;D ;D
ขอบคุณทุกๆๆ คนนะคับที่ช่วยเหลือ
Quote from: pomcoe on March 15, 2013, 03:30:13 PM
ได้แล้วคับ
ผมวน LOOP เอาง่ายๆๆเลย 55
;D ;D ;D ;D ;D ;D
เอา code แปะให้ดูหน่อยสิ เผื่อ คนอื่นๆจะได้ศึกษาด้วย
{
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
output_high(PIN_B1); //led green on
if(vinfa1<0.6){
delay_ms(4000); //delay 4 s.
output_low(PIN_B0); // solinoid valve off
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
if(vinfa1>0.6){
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
while(vinfa1>0.6){
set_adc_channel(0);
delay_us(10);
infa1 = read_adc();
vinfa1 = vbe * (float)infa1;
delay_1mingreen(); //led green blink
}
//delay_ms(2000);
output_low(PIN_B1); //led green off
output_high(PIN_B2); // led red on
output_high(PIN_B0); // solinoid valve on
delay_ms(8000); //delay 8 s.
output_low(PIN_B0); // solinoid valve off
output_low(PIN_B2); // led red off
}
reset_cpu();
}
ขอบคุณครับ
ได้ความรู้เยอะเลยค่ะ