ถามวิธีหาความถี่ด้วย arduino

ประโยชน์ที่คาดหวัง
1.ป้องกันหรือบรรเทาความเสียหายที่อาจเกิดขึ้นกับเซ็นเซอร์​หรือรีเลย์หรือมอเตอร์
รายละเอียดของปัญหา
อยากทราบเรื่องโค้ดหาความถี่
คือว่า ผมใช้nodemcu + arduino + capacitve proximity sensor เพื่อใช้ตรวจสอบอาหารไก่ว่าหมดแล้วยัง
เซ็นเซอร์​นี้จะปล่อยไฟ+12vdcไฟledสว่าง ถ้ามีอาหาร และจะไม่ปล่อยไฟถ้าอาหารหมดและไฟledดับด้วย
ผมใช้รีเลย์12vdc และมีการตัดต่อ สายgnd เข้าpinของnodemcu (input_pullup)​ ก็ทำงานปกติ
ปัญหา​คือ ถ้าอาหารอยู่ก้ำกึ่งหมด หรือมี จะสังเกต ทำให้ไฟled กะพริบถี่มาก และรีเลย์ก็ทำงานดับๆติดๆตามไฟledของเซ็นเซอร์
ผมเกรงว่า​ถ้าเป็นแบบนี้นานๆ ไม่เซ็นเซอร์​พังหรือรีเลย์พัง หรือพังทั้ง2อย่าง
ดังนั้น ผมจะสร้างโค้ด arduino โดยจับสัญญาณ​input จากเซ็นเซอร์​มาหาความถี่
ถ้าสัญญาณ​input(ความถี่)​มาเกิน5ครั้งต่อนาที จะให้ปิดไฟที่มาเลี้ยงเซ็นเซอร์​สัก5นาที แล้วมาจับสัญญาณ​inputใหม่
การหาค่าinterval ระหว่าง millis()​1 และmillis()​2 สัก10ค่า แล้วเอาค่าเฉลี่ยที่ได้มาใช้ ซึ่งเรื่องนี้ผมเขียนโค้ดไม่เป็น

ขอคำชี้แนะจากเพื่อนๆด้วยครับ...

เพราะ​ตอนนี้รีเลย์กับเซ็นเซอร์​พังไปแล้วหลายตัว…
สรุปคือ
1.ขอแนวทางโค้ดหาความถี่
2.และโค้ดการทำloop ให้เก็บค่าความถึ่10ค่าเพื่อเอาค่าเฉลี่ย เห็นใช้ array, matrix เป็นเรื่องที่ผมพยายามแล้วแต่ยังไม่ได้
ขอบคุณ​ครับ​

1 Likes

555 ถามเองตอบเอง

มีการเชื่อม wifi รึป่าวครับ โปรเจคนี้

ต่อด้วยครับ

ไม่ใช้ปัญหาครับ ดูตัวอย่างจากกระทู้นี้ได้เลย

ขอบคุณ​ครับ

ที่มาของฟังก์ชั่นนี้
ผมใช้ capacitive proximity sensor ยี่ห้อ cntd ราคาต่ออัน 450 บาท ใช้ 3 อัน
ใช้เดือนนึงเสีย หมดทั้งสามตัว ปรึกษาคนขายว่า อาจเป็นจากไฟกระชากหรือไฟตก ก็เลยติดตั้ง
surge protetor กันไฟเกิน ไฟตก
คนขายส่งเปลี่ยน 2 ตัว และซิ้ออีก 1ตัว ต่อมาเสียอีก
เลยเปลี่ยนยี่ห้อ ถูกลงมาหน่อย ใช้ไป 2 สัปดาห์ รีเลย์ที่รับสัญญาณจากเซ็นเซอร์นี้ส่งเข้า pin input พัง1ตัว
ผมเลยใส่ไดโอดกันไฟย้อนกลับที่รีเลย์รับสัญญาณทุกตัว
ทำให้รีเลย์เสียน้อยลง แต่รีเลย์ที่รับคำสั่ง output เพื่อไปยัง มอเตอร์หมุนเฟืองให้อาหารพังอีกตัว
ผมสงสัยว่าทำไม เสียง่ายแบบนี้ ทำให้ต้นทุนการเลี้ยงไก่ เพิ่มจากเซ็นเซอร์และรีเลย์ และเสียเวลามากในการเปลี่ยนแต่ละอย่าง เพราะทำเองหมด
ผมสังเกตว่า มีเสียงรัวๆ ดังจากรีเลย์ที่รับเซ็นเซอร์ มาก่อนหน้านี้แล้ว แต่ไม่ใส่ใจ คิดว่าคงไม่เกิดปัญหามากมาย ที่แท้คิดผิด…
ช่วงที่รีเลย์รัวๆนั้น เพราะเซ็นเซอร์อาหารส่งแบบนั้น ไฟled จะกระพริบถี่มาก ซึ่งมักจะเป็นช่วงที่ระดับอาหารที่ปริ่มๆจุดที่เรากำหนดขั้นต่ำให้รีเลย์ทำงานและหยุดทำงาน ถ้าพ้นขีดนี้ไปแล้ว ไม่ว่าต่ำกว่า หรือ สูงกว่าขีดที่กำหนด จะไม่มีเสียงรัวของรีเลย์
ผมก็ได้ตั้งกระทู้นี้ขึ้นมา
จากคำแนะนำของเพื่อนๆให้ใช้ simple timer เลยเขียนโค้ด void นี้ขึ้นมา ให้ทำงานทุก 3 นาที
พอใช้ได้ แต่ยังไม่สมบูรณ์นัก เพื่อนๆลองเอาไปใช้ ปรับปรุง และแชร์ ตามสะดวก ขอบคุณครับ
void check_sensortask()

{
  //D4(upper_tank_sensor ถังบนD4 = GPIO 2,upper_tank_sensor_val),D3(rhodes_tank_sensor"ถังอาหารไก่โร้ดส์"D3 = GPIO 0,rhodes_tank_sensor_val),D6(local_tank_sensor ไก่บ้านD6 = GPIO 12,local_tank_sensor_val),
 // digitalWrite(switch_sensor_local_tank, 0);//active low 24 มิย. 65
       digitalWrite(switch_sensor_upper_tank, 0);//active low 24 มิย. 65
  delay(100);
  upper_tank_sensor_duration = pulseIn(upper_tank_sensor, HIGH,2000);
  Serial.println(upper_tank_sensor_duration);
   Blynk.virtualWrite(V18, upper_tank_sensor_duration);
   if(upper_tank_sensor_duration!=0)
     {
     digitalWrite(switch_sensor_upper_tank, 1);//active low 24 มิย. 65
     upper_tank_sensor_val_high_blynkled_v15.on();
     }
     else
     {
     upper_tank_sensor_val_high_blynkled_v15.off(); 
      }
  digitalWrite(switch_sensor_rhodes_tank, 0);//active low 24 มิย. 65
  delay(100);
  rhodes_tank_sensor_duration = pulseIn(rhodes_tank_sensor, HIGH,2000);
  Serial.println(rhodes_tank_sensor_duration);
   Blynk.virtualWrite(V18, rhodes_tank_sensor_duration);
  if(rhodes_tank_sensor_duration!=0)
    {
     digitalWrite(switch_sensor_rhodes_tank, 1);//active low 24 มิย. 65
     rhodes_tank_sensor_val = 0; //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง. แจ้งให้เต็มก่อนมิฉะนั้นมอเตอร์จะหมุน
     rhodes_tank_sensor_val_high_blynkled_v16.on();
     }
     else
     {
     rhodes_tank_sensor_val_high_blynkled_v16.off(); 
      }
  digitalWrite(switch_sensor_local_tank, 0);//active low 24 มิย. 65
  delay(100);
  local_tank_sensor_duration = pulseIn(local_tank_sensor, HIGH,2000);
  Serial.println(local_tank_sensor_duration);
   Blynk.virtualWrite(V18, local_tank_sensor_duration);
  if(local_tank_sensor_duration!=0 )
    {
     digitalWrite(switch_sensor_local_tank, 1);//active low 24 มิย. 65
     local_tank_sensor_val = 0; //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง. แจ้งให้เต็มก่อนมิฉะนั้นมอเตอร์จะหมุน
     local_tank_sensor_val_high_blynkled_v17.on();
     }
     else
     {
     local_tank_sensor_val_high_blynkled_v17.off(); 
      }
  }ข้อความก่อนจัดรูปแบบ

ทำไฮไลท์โค้ตให้ด้วยครับ จะได้อ่านง่ายๆ

ทำไฮเลต์อย่างไรครับ
ขอบคุณครับ

แก้ไข…
ทำได้แล้วครับ… ลูกเล่นเพียบเลยครับ
ขอเสนอให้ มีการขีดเส้นใต้ ข้อความที่เราต้องการด้วยครับ

อันนี้แถมครับ อิอิ

เรียบร้อย

3กค65


ผมเห็นแบบนี้ตลอด เมื่อเทียบของจริง
ส่วนถูกบคือถังบนและไก่โร้ดส์
ที่ผิดคือ ถังไก่บ้าน
มันโชว์ว่ามีอีก จริงๆแล้วอาหารมันหมดแล้ว แต่อาจเป็นจากโค้ดจับความถี่ว่าเซ็นเซอร์​ทำงานถี่เกิน มันเลยให้แสดงว่าเต็มจะได้ไม่ให้มอเตอร์ทำงาน และledblynkควรเป็นสีแดง หรือon แต่นี้ยังoff และค่าความถี่ต้องมากกว่า0

แสดงว่าโค้ดนี้ทำงานยังไม่สมบูรณ์

1.ผมได้สร้างlogการทำงานของโค้ดนี้ ดูผ่านblynkได้ ว่ามันทำงานอย่างไร

2.ผมอยากลองทำโค้ดจับความถี่อีกแบบหนึ่งว่ามันให้ผลเหมือนกันไหม เช่น จากนี้

ถ้าเพื่อนมีไอเดียดีๆ เอามาฝากด้วยนะ :pray:
4กค65

ตอนแรกเวลาไม่ยอมแสดงในนี้ ทั้งที่ ในv5 แสดงได้
แต่ทำไม (log)​v14ไม่ยอมแสดง
แต่กว่าจะได้จุดนี้เสียเวลา5ชั่วโมง😢
สาเหตุการประกาศ string ของเวลาซ้ำซ้อน คือ ประกาศที่global และอีกที่ประกาศในvoid voidนี้มีคำสั่ง blynk.virtualwrite.v5 เลยแสดงได้
คำสั่ง blynk.virtualwrite.v14มันอยู่คนละฟังก์ชั่นกับ v5 จะไม่โชว์เวลา
วิธีแก้ผมลบ คำประกาศ “String” (ในvoid)​ที่นำหน้าตัวแปรออก
แสดงได้แล้ว
4กค65


เมื่อวานกับวันนี้ ยุ่งกับ String ทั้งวัน 555.
log
ช่วยได้เยอะ ว่ามันช้าจุดไหนครับ
++++++
เซ็นเซอร์ทำงานถี่แต่โค้ดไม่ยอมให้เซ็นเซอร์หยุด(คลิป)

โค้ดที่เกี่ยวข้องคือ
switch_sensor_upper_tank

    timer.setInterval(1000L, check_sensortask);//

void check_sensortask()
  {
  //D4(upper_tank_sensor ถังบนD4 = GPIO 2,upper_tank_sensor_val),D3(rhodes_tank_sensor"ถังอาหารไก่โร้ดส์"D3 = GPIO 0,rhodes_tank_sensor_val),D6(local_tank_sensor ไก่บ้านD6 = GPIO 12,local_tank_sensor_val),
//       digitalWrite(switch_sensor_upper_tank, 0);//active low 24 มิย. 65
  delay(100);
  upper_tank_sensor_duration = pulseIn(upper_tank_sensor, HIGH,2000);
  Serial.println(upper_tank_sensor_duration);
//   Blynk.virtualWrite(V18, upper_tank_sensor_duration);
   if(upper_tank_sensor_duration!=0)
     {
     digitalWrite(switch_sensor_upper_tank, 1);//active low 24 มิย. 65
     upper_tank_sensor_val_high_blynkled_v15.on();
     string_close_open_v4="ค่าความถี่="+String(upper_tank_sensor_duration)+","+string_close+","+string_close_open_v4;
     Blynk.virtualWrite(V4, string_close_open_v4);
     }
     else
     {
     upper_tank_sensor_val_high_blynkled_v15.off();
     string_close_open_v4="ค่าความถี่="+String(upper_tank_sensor_duration)+","+string_open+","+string_close_open_v4;
     Blynk.virtualWrite(V4, string_close_open_v4);
     digitalWrite(switch_sensor_upper_tank, 0);//active low 24 มิย. 65
 
      }
  delay(100);
  rhodes_tank_sensor_duration = pulseIn(rhodes_tank_sensor, HIGH,2000);
  Serial.println(rhodes_tank_sensor_duration);
   Blynk.virtualWrite(V19, rhodes_tank_sensor_duration);
  if(rhodes_tank_sensor_duration!=0)
    {
     digitalWrite(switch_sensor_rhodes_tank, 1);//active low 24 มิย. 65
     rhodes_tank_sensor_val = 0; //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง. แจ้งให้เต็มก่อนมิฉะนั้นมอเตอร์จะหมุน
     string_close_open_v5="ค่าความถี่="+String(upper_tank_sensor_duration)+","+string_close+","+string_close_open_v5;
     Blynk.virtualWrite(V5, string_close_open_v5);
     }
     else
     {
     rhodes_tank_sensor_val_high_blynkled_v16.off(); 
     digitalWrite(switch_sensor_rhodes_tank, 0);//active low 24 มิย. 65
     string_close_open_v5="ค่าความถี่="+String(upper_tank_sensor_duration)+","+string_open+","+string_close_open_v5;
     Blynk.virtualWrite(V5, string_close_open_v5);
      }
  delay(100);
  local_tank_sensor_duration = pulseIn(local_tank_sensor, HIGH,2000);
  Serial.println(local_tank_sensor_duration);
   Blynk.virtualWrite(V20, local_tank_sensor_duration);
  if(local_tank_sensor_duration!=0 )
    {
     digitalWrite(switch_sensor_local_tank, 1);//active low 24 มิย. 65
     local_tank_sensor_val = 0; //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง. แจ้งให้เต็มก่อนมิฉะนั้นมอเตอร์จะหมุน
     local_tank_sensor_val_high_blynkled_v17.on();
     string_close_open_v9="ค่าความถี่="+String(upper_tank_sensor_duration)+","+string_close+","+string_close_open_v9;
     Blynk.virtualWrite(V9, string_close_open_v9);
     }
     else
     {
     local_tank_sensor_val_high_blynkled_v17.off(); 
     digitalWrite(switch_sensor_local_tank, 0);//active low 24 มิย. 65
     string_close_open_v9="ค่าความถี่="+String(upper_tank_sensor_duration)+","+string_open+","+string_close_open_v9;
     Blynk.virtualWrite(V9, string_close_open_v9);
      }
    Blynk.syncAll();            
  }

4กค65
หาวิธีหาความถี่ ในกระทู้นี้ ยิ่งไม่เข้าใจเพราะความรู้เราไปไม่ถึง 555 แต่สุดท้ายในคอมเม้นต์ ไม่ต่างจาก ใช้ pulsein()ครับ เลยใช้แบบนี้ไปก่อน
7กค.65


เย้ pulsein โชว์ผลงานแล้วครับ
ใช้โค้ดนี้ครับ

  local_tank_sensor_duration = pulseIn(local_tank_sensor, LOW,10000);
  Serial.println(local_tank_sensor_duration);
   Blynk.virtualWrite(V20, local_tank_sensor_duration);
  if(local_tank_sensor_duration!=0 )
    {
     digitalWrite(switch_sensor_local_tank, 1);//active low 24 มิย. 65
     local_tank_sensor_val = 0; //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง. แจ้งให้เต็มก่อนมิฉะนั้นมอเตอร์จะหมุน
     local_tank_sensor_val_high_blynkled_v17.on();
     string_close_open_v9="ค่าความถี่="+String(upper_tank_sensor_duration)+","+string_close+","+string_close_open_v9;
     Blynk.virtualWrite(V9, string_close_open_v9);
     }
     else
     {
     local_tank_sensor_val_high_blynkled_v17.off(); 
     digitalWrite(switch_sensor_local_tank, 0);//active low 24 มิย. 65
     string_close_open_v9="ค่าความถี่="+String(upper_tank_sensor_duration)+","+string_open+","+string_close_open_v9;
     Blynk.virtualWrite(V9, string_close_open_v9);
      }

1 Likes

ไม่ลองใช้ winget terminal ดูละครับผมว่ามันดูโปรดีนะ

ขอบคุณ​ครับ
เดี๋ยว​จะ​ลอง​ทำดูครับ

widget terminal


ผลออกมาแบบนี้

เยี่ยมเลย
ขอบคุณ​แอดมินมากครับ

1terminal viiew สามารถรับค่า V ได้ค่าเดียวเองหรือครับ

ตั้งไว้ 1 vPin อ้างอิงเฉยๆ แต่ตัวอื่นก็ส่งตัวแปรมาแสดงได้ครับ