คำตอบที่ได้รับเลือกจากเจ้าของกระทู้
ความคิดเห็นที่ 1
เท่าที่ดูโปรแกรมก็ใกล้เคียงแล้วครับ ตรงส่วนที่ให้วนรอบเรื่อยๆ ก็เช็คง่ายๆว่า
1. key == Enter แล้ว
2. วนลูป while ด้วยเงื่อนไขคือสร้างตัวแปรตัวนึงมันเก็บเป็น flag ไว้ ถ้าตัวนี้เป็น 1 ให้หยุดวน
3. ในลูป ให้รับค่าจากตาชั่งมา แล้วเปรียบเทียบกับค่าที่เก็บไว้ (ทำถูกแล้วครับ แต่ตรง scale2.get_units()-keyHistory[num_count]; มีจุดผิดคือ 4. เอาค่าที่วัดจากตาชั่งมาลบกับ keyHistory[num_count] ที่เป็น string ไม่ได้ ต้องลบกับ grains ที่จขกท. แปลงเป็น double แล้วครับ 2. ตัวแปร grains ต้องประกาศเป็น double ไม่ใช่ int ครับ เพราะจขกท. จะรับค่าที่เป็นจำนวนจริง 3. คำสั่ง get_units() ถ้าใส่ตัวเลขเข้าไปในวงเล็บมันจะวัดค่าเป็นจำนวนครั้งเท่าตัวเลขแล้ว average ออกมานะครับ เผื่อได้ใช้ 4. ควรตั้งตัวแปรมาเก็บค่าที่ลบไว้เผื่อส่งออก serial และ print ครับ)
5. ส่งค่าจากข้อ 4 ออกจอ และ serial
6. เช็คปุ่มกดอีกรอบ ถ้าเป็นปุ่ม clear โดนกด ให้เปลี่ยนค่าตัวแปร flag ในข้อ 2 เป็น 1 โปรแกรมจะได้ออกจากลูปได้
7. รอสักพักก่อนแล้วค่อยวนลูปใหม่เพื่อให้อ่านค่าบนจอได้ อาจจะเอาตัวอย่าง Blink without delay มาดูช่วยนะครับ
จากนั้น การเคลียร์ค่า ให้แก้เงื่อนไขของกรณีกดปุ่ม Clear ให้รวมกรณีที่ flag ถูกตั้งเป็น 1 ไว้ด้วย เพื่อที่ว่าหลังกดปุ่ม Clear ให้ออกลูปแล้ว มันจะได้กลับมาทำงานต่อได้ (ปล. อย่าลืมปรับค่า flag กลับเป็นเหมือนเดิมด้วยนะครับ)
ส่วนที่แนะนำเพิ่มเติมคือ ในเงื่อนไข if(key) อาจจะต้องระบุไปเลยว่าให้นับเฉพาะการกดในช่วงปุ่มตัวเลขเท่านั้น ไม่อย่างนั้นมันจะนับรวมปุ่ม function ไปหมด
แล้วก็ ผมไม่แน่ใจว่าข้างล่างที่ต่อมาหลังเช็คปุ่มเอาไว้ทำอะไรนะครับ แต่แนะนำว่า อย่าประกาศตัวแปรกระจายทั่วโค้ดจะดีกว่านะครับ เอาไว้บนสุดหมดดีกว่า ส่วนการแสดงผลออกจอ ถ้าสร้าง function แยกไว้เลยสำหรับการแสดงผลแล้วค่อยใช้โค้ดหลักเรียก โค้ดจะสะอาดกว่าครับ
ตรง pinMode(button1, INPUT);
digitalWrite(button1, HIGH); //enable pullups to make pin high
แก้เป็น pinMode(button1,INPUT_PULLUP); เลยคำสั่งเดียวก็ได้ครับ สะดวกกว่า
https://www.arduino.cc/reference/en/language/functions/digital-io/pinmode/
สงสัยอะไรถามได้ครับ
1. key == Enter แล้ว
2. วนลูป while ด้วยเงื่อนไขคือสร้างตัวแปรตัวนึงมันเก็บเป็น flag ไว้ ถ้าตัวนี้เป็น 1 ให้หยุดวน
3. ในลูป ให้รับค่าจากตาชั่งมา แล้วเปรียบเทียบกับค่าที่เก็บไว้ (ทำถูกแล้วครับ แต่ตรง scale2.get_units()-keyHistory[num_count]; มีจุดผิดคือ 4. เอาค่าที่วัดจากตาชั่งมาลบกับ keyHistory[num_count] ที่เป็น string ไม่ได้ ต้องลบกับ grains ที่จขกท. แปลงเป็น double แล้วครับ 2. ตัวแปร grains ต้องประกาศเป็น double ไม่ใช่ int ครับ เพราะจขกท. จะรับค่าที่เป็นจำนวนจริง 3. คำสั่ง get_units() ถ้าใส่ตัวเลขเข้าไปในวงเล็บมันจะวัดค่าเป็นจำนวนครั้งเท่าตัวเลขแล้ว average ออกมานะครับ เผื่อได้ใช้ 4. ควรตั้งตัวแปรมาเก็บค่าที่ลบไว้เผื่อส่งออก serial และ print ครับ)
5. ส่งค่าจากข้อ 4 ออกจอ และ serial
6. เช็คปุ่มกดอีกรอบ ถ้าเป็นปุ่ม clear โดนกด ให้เปลี่ยนค่าตัวแปร flag ในข้อ 2 เป็น 1 โปรแกรมจะได้ออกจากลูปได้
7. รอสักพักก่อนแล้วค่อยวนลูปใหม่เพื่อให้อ่านค่าบนจอได้ อาจจะเอาตัวอย่าง Blink without delay มาดูช่วยนะครับ
จากนั้น การเคลียร์ค่า ให้แก้เงื่อนไขของกรณีกดปุ่ม Clear ให้รวมกรณีที่ flag ถูกตั้งเป็น 1 ไว้ด้วย เพื่อที่ว่าหลังกดปุ่ม Clear ให้ออกลูปแล้ว มันจะได้กลับมาทำงานต่อได้ (ปล. อย่าลืมปรับค่า flag กลับเป็นเหมือนเดิมด้วยนะครับ)
ส่วนที่แนะนำเพิ่มเติมคือ ในเงื่อนไข if(key) อาจจะต้องระบุไปเลยว่าให้นับเฉพาะการกดในช่วงปุ่มตัวเลขเท่านั้น ไม่อย่างนั้นมันจะนับรวมปุ่ม function ไปหมด
แล้วก็ ผมไม่แน่ใจว่าข้างล่างที่ต่อมาหลังเช็คปุ่มเอาไว้ทำอะไรนะครับ แต่แนะนำว่า อย่าประกาศตัวแปรกระจายทั่วโค้ดจะดีกว่านะครับ เอาไว้บนสุดหมดดีกว่า ส่วนการแสดงผลออกจอ ถ้าสร้าง function แยกไว้เลยสำหรับการแสดงผลแล้วค่อยใช้โค้ดหลักเรียก โค้ดจะสะอาดกว่าครับ
ตรง pinMode(button1, INPUT);
digitalWrite(button1, HIGH); //enable pullups to make pin high
แก้เป็น pinMode(button1,INPUT_PULLUP); เลยคำสั่งเดียวก็ได้ครับ สะดวกกว่า
https://www.arduino.cc/reference/en/language/functions/digital-io/pinmode/
สงสัยอะไรถามได้ครับ
แสดงความคิดเห็น
อ่านกระทู้อื่นที่พูดคุยเกี่ยวกับ
Arduino
Microprogramming
Microcontroller
Open-source Software
C (ภาษาคอมพิวเตอร์)
ท่านผู้รู้ช่วยดูโค้ด arduino เกี่ยวกับเครื่องชั่งน้ำหนักให้ด้วยครับ เพิ่งหัดทำ งงมากมาย
ผมทำได้แค่พื้นฐานคือให้ชั่ง และแสดงตัวเลขนำ้หนัก รวมทั้งใช้คีย์เพดพิมพ์ตัวเลขได้แค่นั้น
แต่ยังไม่ได้เป้าแบบที่อยากได้ครับ และตอนนี้ไปไม่เป็นแล้วครับ งงเกินจะบรรยายออกมาเป็นภาษาคน
เป้าหมายของเครื่องชั่งน้ำหนัก คือ
1.เปิดเครื่องแล้ว เครื่องสามารถชั่งน้ำหนักได้ปกติ โชว์ทศนิยม 2ตำแหน่ง ... อันนี้ทำมั่วๆได้แล้วครับ
2.เมื่อกดคีย์เพด สามารถใส่ตัวเลขค่าใดๆ และจะเห็นที่จอ LCD (คนละแถวกับเลขที่ชั่งน้ำหนักในข้อ1) ...ข้อนี้สามารถกรอกตัวเลขขึ้นจอได้แล้วครับ
3.เมื่อกด enter ให้เอาเลขน้ำหนักที่ชั่งได้ มาลบกับเลขที่เราคีย์เข้าไปแล้วให้แสดงผลไปอีกที่บนหน้าจออีกจุดหนึ่ง
และถ้าเรายังชั่งน้ำหนักอยู่ตัวเลขในข้อ3จะเปลี่ยนแปลงไปเรื่อยๆ ก็คือลบกันแล้วแสดงตัวเลขหลังลบไปเรื่อยๆครับ .... อันนี้งงครับ ไม่รู้ต้องใช้ตัวแปรอะไรยังไงเพื่อให้มันเอาค่า เอามาลบกันแล้วแสดงออกมาตลอดเวลาครับ
รบกวนท่านผู้รู้แนะนำด้วยครับ
หรือมีใครรับเขียนโค้ดแบบดังกล่าวไหมครับ
ตอนนี้ผมไปไม่เป็นแล้ว
อันนี้โค้ดที่ผมทำไว้ครับ
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "Keypad.h"
#include <HX711.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2); // Set the LCD address to 0x27 in PCF8574 by NXP and Set to 0x3F in PCF8574A by Ti
#define keyPad_Characters 16 // keyPad_Characters 16
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] =
{
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '.', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 3, 4, 2}; //connect to the column pinouts of the keypad
char keyHistory[10]; //allows 15 key presses to be stored + the null char
byte num_count = 0; // Counts numbers in array
char key; // Key Presses
char Clear = 'C';
char Delete = 'D';
char Tare = 'B';
char Enter = 'A';
int grains = 0;
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
HX711 scale2(A1, A2); // parameter "gain" is ommited; the default value 128 is used by the library
#define MAXFLT 6 // 24 bit resolution is 7 digits
int button1 = 11;
int press1 = 0;
void setup()
{
Serial.begin(115200);
lcd.begin();
lcd.setCursor(0, 0);
lcd.print(" Weighting Scale ");
lcd.setCursor(0, 1);
lcd.print("-- C1 --");
delay(3000);
lcd.clear();
scale2.set_scale(33002.f); // this value is obtained by calibrating the scale with known weights;
scale2.tare(); // reset the scale to zero
pinMode(button1, INPUT);
digitalWrite(button1, HIGH); //enable pullups to make pin high
}
void clearData() // Clears char array ...
{
while (num_count != 0)
{ // This can be used for any array size,
keyHistory[num_count--] = 0; //clear array for new data
}
return;
}
void loop()
{
key = keypad.getKey();
if (key)
{
keyHistory[num_count] = key; // store char into data array
lcd.setCursor(num_count, 0); // move cursor to show each new char stored into data array
lcd.print(keyHistory[num_count]); // print char at said cursor
Serial.println(keyHistory[num_count]);
num_count++; // increment data array by 1 to store new char, also keep track of the number of chars entered
}
if (key == Tare) // Tares Scale to zero, clears lcd, clears array ,กด B = Tare ล้างค่าน้ำหนักที่คีย์ใส่ และค่าน้ำหนักที่ชั่ง ให้เป็น 0
{
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("<TARE>");
delay(500);
clearData();
scale2.tare();
lcd.clear();
}
if (key == Clear) // Clears LCD, blinks backlight ,กด C = Clear ล้างค่าน้ำหนักที่คีย์ใส่ ให้เป็น 0 แต่ค่าน้ำหนักที่ชั่งจะยังคงอยู่ไม่เปลี่ยนไป
{
lcd.clear();
lcd.print("<CLEAR>");
delay(500);
lcd.clear();
clearData();
lcd.setCursor(8, 1);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*ตรงนี้งงว่า จะกำหนดให้มันมาลบกันได้ยังถ้ากด Enter ครับ
if (key == Enter) // Starts powder measure routine
{
keyHistory[num_count] = 0; // Allows use of decimals in array
grains = atof(keyHistory);
// !!?? จะต้องแก้pยังไงให้เป็นว่า ถ้าทำการกด enter (ปุ่มกดที่คีย์เพด "A" )ให้ทำการประมวลผลตัวเลข โดยเอาค่าน้ำหนักที่ได้ ไปลบ กับตัวเลขที่คีย์ลงไว้ แล้วแสดงผลตัวเลขออกมาที่จอ ตัวที่10 แถวที่2 ???? โค้ดด้านล่างผมทำแบบไม่เข้าใจ ซึ่งน่าจะผิดหลัก มันต้องทำตัวแปรแบบไหน ให้มันลบกันแล้วแสดงผลซำ้ๆวนตลอดเวลาที่เปิดเครื่อง หรือจนกว่าจะล้างข้อมูลที่คีย์ไว้ครับ.....
scale2.get_units()-keyHistory[num_count];
lcd.setCursor(10, 1);
lcd.print(scale2.get_units(2)-keyHistory[num_count]);
}
*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float r;
char buf[MAXFLT + 1];
r = scale2.get_units(5); // average readings
Serial.println(dtostrf(r, MAXFLT, 4, buf));
lcd.setCursor(0, 1);
lcd.print(dtostrf(r, MAXFLT, 2, buf)); // average readings
{
press1 = digitalRead(button1);
if (press1 == LOW)
{
scale2.tare();
}
else {
/// do nothing
}
}
//การแสดงผลคำต่างๆที่จอlcd
lcd.setCursor(10, 0);
lcd.print("<WT.in");
lcd.setCursor(6, 1);
lcd.print("kg>");
lcd.setCursor(14, 1);
lcd.print("kg");
}