86
Table of Contents
1 Introduction...........................................................................................................................3
2 Feature ...................................................................................................................................3
3 Application ............................................................................................................................3
4 Power Amplifier Circuit .......................................................................................................5
87
1 Introduction
Voice Record Module is base on ISD1820, which a multiple‐message record/playback
device.It can offers true single‐chip voice recording, no‐volatile storage, and playback
capability for 8 to 20 seconds. The sample is 3.2k and the total 20s for the Recorder.
This module use is very easy which you could direct control by push button on board or
byMicrocontroller such as Arduino, STM32, ChipKit etc. Frome these, you can easy control
record ,playback and repeat and so on.
2 Feature
➢ Push‐button interface, playback can be edge or level activated
➢ Automatic power‐dwon mode
➢ On‐chip 8Ω speaker driver
➢ Signal 3V Power Supply
➢ Can be controlled both manually or by MCU
➢ Sample rate and duration changable by replacing a single resistor
➢ Record up to 20 seconds of audio
➢ Dimensions: 37 x 54 mm
3 Application
Typical schematic list as follows.
If you want change record duration, an external resistor is necessary to select the record
duration and sampling frequency, which can range from 8 – 20 seconds (4‐12kHz sampling
frequency). The Voice Record Module of our provide default connect 100k resistor by short
cap.So the default record duration is 10s.
88
MIC
SP+
SP‐
1. VCC– 3.3V power supply
2. GND– Power ground
3. REC – The REC input is an active‐HIGH record signal. The module starts recording
whenever REC is HIGH. This pin must remain HIGH for the duration of the recording.
REC takes precedence over either playback(PLAYL or PLAYE) signal.
4. PLAYE – Playback, Edge‐activated: When a HIGH‐going transition is detected on
continues until an End‐of‐Message (EOM) marker is encountered or the end of the
memory space is reached.
5. PLAYL – Playback, Level‐activated, when this input pin level transits for LOW to HIGH, a
playback cycle is initiated.
6. Speaker Outputs – The SP+ and SP‐ pins provide direct drive for loudspeakers with
impedances as low as 8Ω.
7. MIC – Microphone Input, the microphone input transfers its signals to the on‐chip
preamplifier.
8. FT – Feed Through: This mode enable the Microphone to drive the speaker directly.
9. P‐E – Play the records endlessly.
Record Operate Guide
1. Push REC button then the RECLED will light and keep push until record end.
2. Release the REC button
3. Select Playback mode: PLAYE, just need push one time, and will playback all of the
record or power down ; PLAYL, you need always push this button until you want to stop
playback record or end ; When short P‐E jumper the record will playback time a time
until jumper off or power down
4. FT mode, when short FT jumper, that means all of you speak to MIC will direct playback
to Speaker.
89
4 Power Amplifier Circuit
If you want extern power amplifier circuit to Speakers, you can use LM386, D2283,
D2322,TA7368, MC34119 etc amplifier IC. Note, SP+ or SP‐ is you do not want to use, must
vacant, donot connect to GND. Used LM386 power amplifier circuit as below:
ภาคผนวก ค
ขอ้ มูล Sensor HC-SR04
91
HC-SR04 User Guide
1.Ultrasonic Distance Measurement Principles
The transmitter emits a 8 bursts of an directional 40KHz ultrasonic wave
when triggered and starts a timer. Ultrasonic pulses travel outward until they
encounteran object, The object causes the the wave to be reflected back towards the
unit. The ultrasonic receiver would detect the reflected wave and stop the stop timer.
The velocity of the ultrasonic burst is 340m/sec. in air. Based on the number of counts
by the timer, the distance can be calculated between the object and transmitter The
TRD Measurement formula is expressed as: D = C X T which is know as the
time/rate/distance measurement formula where D is the measured distance, and R is
the propagation velocity (Rate) in air (speed of sound) and T represents time. In this
application T is devided by 2 as T is double the timevalue from transmitter to
object back to receiver.
2.Product Features
Features
⚫ Stable performance (Xtal.)
⚫ Accurate distance measurement
⚫ High-density SMD Board
⚫ Close Range (2cm)
Uses
⚫ Robotics barrier
⚫ Object distance measurement
⚫ Level detection
⚫ Security systems
⚫ Vehicle detection/avoidance
3.Product Views 92
BACK
4.Module Pin Asignments Pin Function Description
5V power supply
Pin Symbol Trigger Input pin
1 VCC Receiver Output pin
2 Trig Power ground
3 Echo
4 GND
5.Electrical Specifications
WARARNING
Do Not connect Module with Power Applied! Always apply power after connecting
Connect "GND" Terminal first
Electrical Parameters HC-SR04 Ultrasonic Module
Operating Voltage 5VDC
Operating Current 15mA
40KHz
Operating Frequency 4m
Max. Range 2cm
Nearest Range
15 Degrees
Measuring Angle 10us min. TTL pulse
Input Trigger Signal
Output Echo Signal 93
Board Dimensions TTL level signal, proportional to
Board Connections distance
1-13/16" X 13/16" X 5/8"
4 X 0.1" Pitch Right Angle Header Pins
93
6.Module Operation
Set Trig and Echo Low to initalize module. Place a minimum
10us Highlevel pulse to "Trigger" (module will automatically send eight
40KHz acoustic bursts). At the same time, Gate the microcontroller timer
to start timing.
Wait to capture the rising edge output of ECHO port to stop the
timer. Nowread the time of the counter, which is the ultrasonic
propagation time in the air. According to the formula: Distance = (ECHO
high level time X ultrasonic velocity (Speed of Sound in air 340m/sec) /
2, you can calculate the distance to the obstacle.
For best results and maximum range, the Object should be
larger than 0.5M2the nearer the target object, the smaller it
may be
94
7.ModuleTiming
Trigger 10us min. start measurement from microcontroller.
Max Rep. Rate: 50us
ECHO Output pulse to microcontroller, width is the time from last of 8
40KHzbursts to detected reflected signal (microcontroller Timer gate
signal)
Distance in cm = echo pulse width in uS/58 Distance
in inch = echo pulse width in uS/148
Information obtained from or supplied by Mpja.com or Marlin P. Jones and Associates inc. is
supplied as a service to our customers and accuracy is not guaranteed nor is it definitive of any
particular part or manufacturer. Use of information and suitability for any application is at users
own discretion and user assumes all risk.
ภาคผนวก ง
โค้ดเวบ็ ไซต์ระบบจดั เกบ็ อุปกรณ์
96
โคด้ สำหรบั ระบบจดั เก็บอุปกรณ์
Code.gs
function doGet(e) {
if(!e.parameter.page){
var htmlOutput =HtmlService.createTemplateFromFile('index')
return htmlOutput.evaluate()
}
return HtmlService.createTemplateFromFile(e.parameter['page']).evaluate()
.setTitle("NTstock by ENS")
}
function getUrl(){
var url = ScriptApp.getService().getUrl()
return url
}
function processForm(formObject){
var result = "";
if(formObject.searchtext){
result = search(formObject.searchtext);
}
return result;
}
function search(searchtext){
var spreadsheetId = '1ikD7kmFa0t-ZmFd9UYJZSZZxdwuqB-rd0r9g5CPNgIQ';
var dataRage = 'resFrm!A2:I';
var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values;
var ar = [];
data.forEach(function(f) {
if (~f.indexOf(searchtext)) {
ar.push(f);
}
});
return ar;
}
var SCRIPT_PROP = PropertiesService.getScriptProperties();
97
var sheetID= '1ikD7kmFa0t-ZmFd9UYJZSZZxdwuqB-rd0r9g5CPNgIQ'
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty(sheetID, doc.getId());
}
function uploadFile(data, file,fname,lname,N_name,category,brand,tel,serial) {
try {
var folder=DriveApp.getFolderById('1JsRTgRzlnZ_3Wmwu7VgAmUYUwOMsDHrw');
var contentType = data.substring(5,data.indexOf(';')),
bytes = Utilities.base64Decode(data.substr(data.indexOf('base64,')+7)),
blob = Utilities.newBlob(bytes, contentType, file),
file = folder.createFolder([N_name+category+new Date()]).createFile(blob),
filelid =file.getId() ;
image = 'https://drive.google.com/uc?id='+filelid
var lock = LockService.getPublicLock();
lock.waitLock(30000);
var doc = SpreadsheetApp.openById(sheetID);
var sheet = doc.getSheetByName("resFrm");
var row = [new Date,fname,lname,N_name,category,brand,"'"+tel,serial,image];
var msgforSend = "";
msgforSend = '\n' + 'ว/ด/ป: '+ Date() + '\n' +
'ช่อื -นามสกุล: ' + fname + " " + lname + '\n' +
'ช่ือเล่น: ' + N_name + '\n' +
'หมวดหม:ู่ ' + category+ '\n'+
'ยหี่ อ้ : ' +brand+ '\n' +
'เบอร์: ' +tel + '\n' +
'S/N: ' + serial;
var GoogleIamge = "https://drive.google.com/uc?id=" + file.getId();
var Token ="1sW8DW2KiygKEjt7LiG3qQdOJIYK9ckFpGhwdrjP4hk";
sendLineNotify(msgforSend,GoogleIamge,Token);
sheet.appendRow(row)
return "OK";
} catch (f) {
return f.toString();
} finally {
lock.releaseLock();
98
}
}
function uploadFile2(data, file,fname,lname,N_name,category,brand,tel,serial) {
try {
var folder=DriveApp.getFolderById('1JsRTgRzlnZ_3Wmwu7VgAmUYUwOMsDHrw');
var contentType = data.substring(5,data.indexOf(';')),
bytes = Utilities.base64Decode(data.substr(data.indexOf('base64,')+7)),
blob = Utilities.newBlob(bytes, contentType, file),
file = folder.createFolder([N_name+category+new Date()]).createFile(blob),
filelid =file.getId() ;
image = 'https://drive.google.com/uc?id='+filelid
var lock = LockService.getPublicLock();
lock.waitLock(3000);
var doc = SpreadsheetApp.openById(sheetID);
var sheet = doc.getSheetByName("addFrm");
var row = [new Date,fname,lname,N_name,category,brand,"'"+tel,serial,image];
var msgforSend = "";
msgforSend = '\n' + 'ว/ด/ป: '+ Date() + '\n' +
'ชือ่ -นามสกุล: ' + fname + " " + lname + '\n' +
'ชื่อเล่น: ' + N_name + '\n' +
'หมวดหม:ู่ ' + category+ '\n'+
'ยี่หอ้ : ' +brand+ '\n' +
'เบอร:์ ' +tel + '\n' +
'S/N: ' + serial;
var GoogleIamge = "https://drive.google.com/uc?id=" + file.getId();
var Token = "oNZe1iOQWzallBrneVhJ2oRutV33FcKiQBytq29yTDL";
sendLineNotify(msgforSend,GoogleIamge, Token);
sheet.appendRow(row)
return "OK";
} catch (f) {
return f.toString();
} finally {
lock.releaseLock();
}
}
99
function sendLineNotify(messageforSend,Picture, Token) {
// ระบุ Token ของ Line Notify ** [3] **
var token = Token;
var Image = Picture;
var DataSend = {
'message' : messageforSend,
'imageThumbnail': Image,
'imageFullsize' : Image,
}
var params = {
"method": "post",
"payload": DataSend,
"headers": {
'Content-Type': 'application/x-www-form-urlencoded',
"Authorization": "Bearer " + token
}
};
/// ต้อง Share Google Sheet แบบทุกคนที่มีลงิ กน์ เี้ ข้าถงึ ได้ ** [4] **
/// ไมง่ ้ันจะ Error >> https://www.googleapis.com/auth/script.external_request
//------------------------------------------------------------
UrlFetchApp.fetch("https://notify-api.line.me/api/notify", params);
//-------------------------------------------------------------
}
index
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Mitr">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-
alpha1/css/bootstrap.min.css" integrity="sha384-
r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I"
crossorigin="anonymous">
<!-- Font Awesome CSS -->
<script src="https://kit.fontawesome.com/6a972cf3a7.js"
crossorigin="anonymous"></script>
100
<link rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-
50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
crossorigin="anonymous">
<style>
body {
font-family: "Mitr"
}
</style>
</head>
<body >
<div class="container-fluid">
<br>
<div class="row">
<div class="col ">
<div class="row">
<div class="col-md-4 mx-auto">
<nav class="navbar navbar-expand-sm navbar-dark bg-warning flex-sm-nowrap flex-
wrap">
<div class="container-fluid">
<button class="navbar-toggler flex-grow-sm-1 flex-grow-0 me-4" type="button"
data-bs-toggle="collapse" data-bs-target="#navbar5">
<span class="navbar-toggler-icon"></span>
</button>
span class="navbar-brand flex-grow-1"><i class="fas fa-shopping-cart"></i>ระบบ
stock</span>
<div class="navbar-collapse collapse flex-grow-1 justify-content-center"
id="navbar5">
<ul class="navbar-nav mx-auto">
<li class="nav-item">
<?var url = getUrl();?><a class="nav-link" href='<?=url?>?page=form'><i class="fas
fa-address-book"></i> เบิกอุปกรณ<์ /a>
<?var url = getUrl();?><a class="nav-link" href='<?=url?>?page=form2'><i class="fas
fa-notes-medical"></i> เพิ่มอปุ กรณ<์ /a>
</li>
</ul>
101
</div>
<div class="flex-grow-1">
<!--spacer-->
</div>
</div>
</nav>
<div class="card text-center">
<div class="card-header bg-secondary text-light">
<i class="fas fa-clipboard"></i> NTStock
</div>
<div class="card-body">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<!-- ## สร้างตาราง ------------------------------------------------ -->
<div id="search-results " class="table-responsive">
<!-- แสดงขอ้ มูลท่นี ่ี -->
</div>
<!-- ## จบตาราง ------------------------------------------------ -->
</div>
</div>
</div>
<!--##JAVASCRIPT ------------------------------------------ -->
<script>
window.addEventListener("load", preventFormSubmit, true);
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
102
}
}
//ทำการสง่ ค่าจากฟอร์ม
function handleFormSubmit(formObject) {
google.script.run.withSuccessHandler(createTable).processForm(formObject);
document.getElementById("search-form").reset();
}
//สร้างตารางและข้อมูลในตาราง
function createTable(dataArray) {
if(dataArray && dataArray !== undefined && dataArray.length != 0){
var result = "<table class='table table-sm table-striped table-hover' id='dtable'>"+
"<thead style='white-space: nowrap'>"+
"<tr>"+
"<th scope='col'>วันที่"+
"<th scope='col'>ชือ่ </th>"+
"<th scope='col'>นามสกุล</th>"+
"<th scope='col'>ชื่อเล่น</th>"+
"<th scope='col'>หมวดหม<ู่ /th>"+
"<th scope='col'>ยี่ห้อ</th>"+
"<th scope='col'>S/N</th>"+
"<th scope='col'>โทรศพั ท์</th>"+
"<th scope='col'>รูปภาพ</th>"+
"</tr>"+
"</thead>";
for(var i=0; i<dataArray.length; i++) {
result += "<tr>";
for(var j=0; j<dataArray[i].length; j++){
result += "<td class=\"table-info\">" + dataArray[i][j] + "</td";
}
result += "<td class=\"table-info\">"+`<img src ="${dataArray[1][8]}" style =
"width:100px; height:100px;">`+"</td>";
result += "</tr>";
}
result += "</table>";
var div = document.getElementById('search-results');
div.innerHTML = result;} else{
103
var div = document.getElementById('search-results');
//div.empty()
//div.innerHTML = "ไม่พบข้อมูลท่ีค้นหา!";
}
}
</script>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-
p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8"
crossorigin="anonymous"></script>
</body>
</html>
Form1.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Mitr">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-
alpha1/css/bootstrap.min.css"
integrity="sha384-
r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I"
crossorigin="anonymous">
<!-- Font Awesome CSS -->
<script src="https://kit.fontawesome.com/6a972cf3a7.js"
crossorigin="anonymous"></script>
<script src="https://unpkg.com/[email protected]/dist/html5-
qrcode.min.js"></script>
<link rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.8.1/css/all.css"
104
integrity="sha384-
50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
crossorigin="anonymous">
<style>
body {
font-family: "Mitr"
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-auto mx-auto">
<nav class="navbar navbar-expand-sm navbar-dark bg-secondary flex-sm-nowrap
flex-wrap">
<div class="container-fluid">
<button class="navbar-toggler flex-grow-sm-1 flex-grow-0 me-2" type="button"
data-bs-toggle="collapse" data-bs-target="#navbar5">
<span class="navbar-toggler-icon"></span>
</button>
<span class="navbar-brand flex-grow-1"><i class="fas fa-address-card"></i> ฟอรม์
เบกิ อปุ กรณ<์ /span>
<div class="navbar-collapse collapse flex-grow-1 justify-content-center"
id="navbar5">
<ul class="navbar-nav mx-auto">
<li class="nav-item">
<?var url = getUrl();?><a class="nav-link" href='<?=url?>?page=index'><i class="fas
fa-home"></i> กลับสหู่ น้าหลกั </a>
</li>
</ul>
</div>
<div class="flex-grow-1">
<!--spacer-->
</div>
</div>
105
</nav>
<div class="card">
<div class="card-header bg-warning text-light">
เบกิ อปุ กรณ์
</div>
<div class="card-body">
<form class="main" id="form" novalidate="novalidate"style="max-width:
600px;margin: 20px auto;">
<div id="forminner">
<div class="form-row">
<div class="form-group col-md-auto">
<label for="name">ช่อื ผเู้ บกิ </label>
<input type="text area"
class="form-control"
id="fname"
name="fname"
maxlength="15"
placeholder="กรอกชอ่ื ">
</div>
<div class="form-group col-md-auto">
<label for="lname">นามสกุล</label>
<inputtype="text area"
class="form-control"
id="lname"
name="lname"
maxlength="15"
placeholder="กรอกนามสกุล">
</div>
<div class="form-group col-md-auto">
<label for="N_name">ชอ่ื เล่น</label>
<input type="text area"
class="form-control"
id="N_name"
name="N_name"
maxlength="20"
placeholder="กรอกช่ือเลน่ ">
106
</div>
<div class="form-group col-md-auto">
<label for="category">หมวดหมู่</label>
<input type="text area"
class="form-control"
id="category"
name="category"
maxlength="50"
placeholder="กรอกหมวดหม"ู่ >
</div>
<div class="form-group col-md-auto">
<label for="brand">ยีห่ อ้ </label>
<input type="text area"
class="form-control"
id="brand"
name="brand"
maxlength="50"
placeholder="กรอกย่หี ้อ">
</div>
<div class="form-group col-md-auto">
<label for="tel">เบอร์โทร</label>
<input type="text"
class="form-control"
id="tel" name="tel"
maxlength="10"
placeholder="xxx-xxxxxxx">
</div>
<div class="form-group col-md-auto">
<label for="serial">S/N</label>
<input type="text"
class="form-control"
id="serial"
name="serial"
maxlength="50"
placeholder="กรอกซีเรยี ล / สเเกนอาร์โคด้ ">
</div>
107
<div id="qr-reader" style="width: 600px"></div>
<!--อปั โหลดรูภาพ-->
<div class="row">
<div class="form-group col-md-auto">
<span>เลือกรูปภาพ</span>
<div class="btn">
<input id="files" type="file">
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="input-field col s6 text-center">
<button type="submit" class="btn btn-warning mb-2" id="button"
onclick="submitForm(); return false;">
บันทกึ ข้อมลู
</button>
</div>
</div>
</div>
</div>
</form>
<div >
<div id="success" style="display:none">
<h4 class="left-align teal-text">
<center>
บันทกึ ข้อมลู เรยี บร้อย!
</center>
</h4>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
108
</div>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"integrity="sha5
12894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/
3e7Jo4EaG7TubfWGUrMQ=="crossorigin="anonymous"></script>
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.
min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
} );
var file, reader = new FileReader();
reader.onloadend = function (e) {
if (e.target.error != null) {
showError("File " + file.name + " could not be read.");
return;
} else {
google.script.run
.withSuccessHandler(showSuccess)
.uploadFile2(e.target.result, file.name,
$('input#fname').val(),
$('input#lname').val(),
$('input#N_name').val(),
$('input#category').val(),
$('input#brand').val(),
$('input#tel').val(),
$('input#serial').val()
);
}
};
// Scanner
function onScanSuccess(decodedText, decodedResult) {
console.log(`Code scanned = ${decodedText}`, decodedResult);
document.getElementById("serial").value = decodedText;
}
109
var html5QrcodeScanner = new Html5QrcodeScanner(
"qr-reader", { fps: 10, qrbox: 250 });
html5QrcodeScanner.render(onScanSuccess);
function showSuccess(e) {
if (e === "OK") {
$('#forminner').hide();
$('#success').show();
$('#image').hide();
} else {
showError(e);
}
}
function restartForm() {
$('#form').trigger("reset");
$('#forminner').show();
$('#success').hide();
$('#button').show();
}
function submitForm() {
var fname= $('input#fname').val();
if (fname.length === 0) {
showError("กรณุ ากรอกช่ือ");
return;
}
if(!/^[ก-๏\s]+$/.test(fname)){
showError("กรณุ ากรอกเฉพาะภาษาไทย!")
return;
}
var lname = $('input#lname').val();
if (lname.length === 0) {
showError("กรุณากรอกนามสกุล");
return;
}
if(!/^[ก-๏\s]+$/.test(lname)){
110
showError("กรณุ ากรอกเฉพาะภาษาไทย!")
return;
}
var N_name = $('input#N_name').val();
if (N_name.length === 0) {
showError("กรุณากรอกช่ือเลน่ ");
return;
}
if(!/^[ก-๏\s]+$/.test(N_name)){
showError("กรุณากรอกเฉพาะภาษาไทย!")
return;
}
var category = $('input#category').val();
if (category.length === 0) {
showError("กรุณากรอกหมวดหมู"่ );
return;
}
if(!/^[A-Za-z\s]+$/.test(category)){
showError("กรณุ ากรอกเฉพาะอังกฤษ!(A-Za)")
return;
}
var brand= $('input#brand').val();
if (brand.length === 0) {
showError("กรุณากรอกยีห่ ้อ");
return;
}
if(!/^[A-Za-z\s]+$/.test(brand)){
showError("กรุณากรอกเฉพาะอังกฤษ!(A-Za)")
return;
}
var tel = $('input#tel').val();
if (tel.length === 0||tel.length<10) {
showError("กรุณากรอกหมายเลขโทรศัพท"์ );
return;
}
111
if(!/^[0-9]+$/.test(tel)){
showError("กรณุ ากรอกเฉพาะตวั เลขค่ะ!(0-9)")
return;
}
var serial = $('input#serial').val();
if (serial.length === 0) {
showError("กรุณากรอกS/N");
return;
}
var files = $('#files')[0].files;
if (files.length === 0) {
showError("กรุณาเลอื กไฟล์ภาพ");
return;
}
document.getElementById("button").style.display = "none"
file = files[0];
if (file.size > 1024 * 1024 * 20) {
showError("The file size should be < 20 MB. ");
return;
}
showMessage("...ระบบกำลังบนั ทกึ ข้อมลู ...");
reader.readAsDataURL(file);
}
function showError(e) {
Swal.fire({
title: 'คุณกรอกข้อมลู ยงั ไมค่ รบ!',
text: e,
icon: 'error',
confirmButtonText: 'ตกลง'
})
}
function showMessage(e) {
Swal.fire({
title: '...กรณุ ารอสักครู...',
text: '...ระบบกำลังบันทึกขอ้ มลู ...',
112
showConfirmButton: false,
timer: 3000
})
}
$(document).ready(function () {
$('select').material_select();
});
document.getElementById("files").onchange = function () {
var reader = new FileReader();
reader.onload = function (e) {
document.getElementById("image").src = e.target.result;
$('#image').show();
};
reader.readAsDataURL(this.files[0]);
};
</script>
<script src="//cdn.jsdelivr.net/npm/sweetalert2@10"></script>
</body>
</html>
Form2.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Mitr">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-
alpha1/css/bootstrap.min.css"
integrity="sha384r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9lu
XQOfXJCJ4I" crossorigin="anonymous">
<!-- Font Awesome CSS -->
<script src="https://kit.fontawesome.com/6a972cf3a7.js"
crossorigin="anonymous"></script>
<script src="https://unpkg.com/[email protected]/dist/html5-
qrcode.min.js"></script>
113
<link rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.8.1/css/all.css"
integrity="sha384-
50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
crossorigin="anonymous">
<style>
body {
font-family: "Mitr"
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-auto mx-auto">
<nav class="navbar navbar-expand-sm navbar-dark bg-secondary flex-sm-nowrap
flex-wrap">
<div class="container-fluid">
<button class="navbar-toggler flex-grow-sm-1 flex-grow-0 me-2" type="button"
data-bs-toggle="collapse" data-bs-target="#navbar5">
<span class="navbar-toggler-icon"></span>
</button>
<span class="navbar-brand flex-grow-1"><i class="fas fa-address-card"></i> ฟอรม์
เพ่มิ อุปกรณ<์ /span>
<div class="navbar-collapse collapse flex-grow-1 justify-content-center"
id="navbar5">
<ul class="navbar-nav mx-auto">
<li class="nav-item">
<?var url = getUrl();?><a class="nav-link" href='<?=url?>?page=index'><i class="fas
fa-home"></i> กลับส่หู น้าหลัก</a>
</li>
</ul>
</div>
<div class="flex-grow-1">
114
<!--spacer-->
</div>
</div>
</nav>
<div class="card">
<div class="card-header bg-warning text-light">
เพ่มิ อุปกรณ์
</div>
<div class="card-body">
<form class="main" id="form" novalidate="novalidate"style="max-width:
600px;margin: 20px auto;">
<div id="forminner">
<div class="form-row">
<div class="form-group col-md-auto">
<label for="name">ชือ่ ผู้เพิ่ม</label>
<inputtype="text area"
class="form-control"
id="fname"
name="fname"
maxlength="15"
placeholder="กรอกชื่อ">
</div>
<div class="form-group col-md-auto">
<labelfor="lname">นามสกุล</label>
input type="text area"
class="form-control"
id="lname"
name="lname"
maxlength="15"
placeholder="กรอกนามสกุล">
</div>
<div class="form-group col-md-auto">
<label for="N_name">ช่อื เลน่ </label>
<input type="text area"
class="form-control"
id="N_name"
115
name="N_name"
maxlength="20"
placeholder="กรอกชอ่ื เลน่ ">
</div>
<div class="form-group col-md-auto">
<label for="category">หมวดหมู่</label>
<input type="text area"
class="form-control"
id="category"
name="category"
maxlength="50"
placeholder="กรอกหมวดหม"ู่ >
</div>
div class="form-group col-md-auto">
<label for="brand">ยห่ี ้อ</label>
<input type="text area"
class="form-control"
id="brand"
name="brand"
maxlength="50"
placeholder="กรอกย่หี ้อ">
</div>
<div class="form-group col-md-auto">
<label for="tel">เบอร์โทร</label>
<input type="text"
class="form-control"
id="tel" name="tel"
maxlength="10"
placeholder="xxx-xxxxxxx">
</div>
<div class="form-group col-md-auto">
<label for="serial">S/N</label>
<input type="text"
class="form-control"
id="serial"
name="serial"
116
maxlength="50"
placeholder="กรอกซีเรยี ล / สเเกนอาร์โค้ด">
</div>
ฺ <div id="qr-reader" style="width: 600px"></div>
<!--อัปโหลดรภู าพ-->
<div class="row">
<div class="form-group col-md-auto">
<span>เลอื กรูปภาพ</span>
<div class="btn">
<input id="files" type="file">
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="input-field col s6 text-center">
<button type="submit" class="btn btn-warning mb-2" id="button"
onclick="submitForm(); return false;">
บันทึกข้อมลู
</button>
</div>
</div>
</div>
</div>
</form>
<div >
<div id="success" style="display:none">
<h4 class="left-align teal-text">
<center>
บันทึกข้อมลู เรยี บร้อย!
</center>
</h4>
</div>
</div>
</div>
</div>
</div>
117
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
integrity="sha512-
894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e
7Jo4EaG7TubfWGUrMQ=="
crossorigin="anonymous"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js">
</script>
<script>
document.addEventListener('DOMContentLoaded', function () {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
});
var file, reader = new FileReader();
reader.onloadend = function (e) {
if (e.target.error != null) {
showError("File " + file.name + " could not be read.");
return;
} else {
google.script.run
.withSuccessHandler(showSuccess)
.uploadFile2(e.target.result, file.name,
$('input#fname').val(),
$('input#lname').val(),
$('input#N_name').val(),
$('input#category').val(),
$('input#brand').val(),
$('input#tel').val(),
$('input#serial').val()
);
}
118
};
// Scanner
function onScanSuccess(decodedText, decodedResult) {
console.log(`Code scanned = ${decodedText}`, decodedResult);
document.getElementById("serial").value = decodedText;
}
var html5QrcodeScanner = new Html5QrcodeScanner(
"qr-reader", { fps: 10, qrbox: 250 });
html5QrcodeScanner.render(onScanSuccess);
function showSuccess(e) {
if (e === "OK") {
$('#forminner').hide();
$('#success').show();
$('#image').hide();
} else {
showError(e);
}
}
function restartForm() {
$('#form').trigger("reset");
$('#forminner').show();
$('#success').hide();
$('#button').show();
}
function submitForm() {
var fname= $('input#fname').val();
if (fname.length === 0) {
showError("กรุณากรอกชื่อ");
return;
}
if(!/^[ก-๏\s]+$/.test(fname)){
showError("กรุณากรอกเฉพาะภาษาไทย!")
return;
}
119
var lname = $('input#lname').val();
if (lname.length === 0) {
showError("กรุณากรอกนามสกุล");
return;
}
if(!/^[ก-๏\s]+$/.test(lname)){
showError("กรณุ ากรอกเฉพาะภาษาไทย!")
return;
}
var N_name = $('input#N_name').val();
if (N_name.length === 0) {
showError("กรุณากรอกชื่อเล่น");
return;
}
if(!/^[ก-๏\s]+$/.test(N_name)){
showError("กรณุ ากรอกเฉพาะภาษาไทย!")
return;
}
var category = $('input#category').val();
if (category.length === 0) {
showError("กรุณากรอกหมวดหม"ู่ );
return;
}
if(!/^[A-Za-z\s]+$/.test(category)){
showError("กรณุ ากรอกเฉพาะอังกฤษ!(A-Za)")
return;
}
var brand= $('input#brand').val();
if (brand.length === 0) {
showError("กรุณากรอกยห่ี ้อ");
return;
}
if(!/^[A-Za-z\s]+$/.test(brand)){
showError("กรุณากรอกเฉพาะอังกฤษ!(A-Za)")
return;
}
120
var tel = $('input#tel').val();
if (tel.length === 0||tel.length<10) {
showError("กรณุ ากรอกหมายเลขโทรศพั ท"์ );
return;
}
if(!/^[0-9]+$/.test(tel)){
showError("กรุณากรอกเฉพาะตัวเลขค่ะ!(0-9)")
return;
}
var serial = $('input#serial').val();
if (serial.length === 0) {
showError("กรณุ ากรอกS/N");
return;
}
var files = $('#files')[0].files;
if (files.length === 0) {
showError("กรณุ าเลือกไฟล์ภาพ");
return;
}
document.getElementById("button").style.display = "none"
file = files[0];
if (file.size > 1024 * 1024 * 20) {
showError("The file size should be < 20 MB. ");
return;
}
showMessage("...ระบบกำลังบนั ทึกข้อมูล...");
reader.readAsDataURL(file);
}
function showError(e) {
Swal.fire({
title: 'คุณกรอกข้อมลู ยงั ไมค่ รบ!',
text: e,
icon: 'error',
confirmButtonText: 'ตกลง'
})
}
121
function showMessage(e) {
Swal.fire({
title: '...กรณุ ารอสักคร.ู ..',
text: '...ระบบกำลังบนั ทกึ ขอ้ มลู ...',
showConfirmButton: false,
timer: 3000
})
}
$(document).ready(function () {
$('select').material_select();
});
document.getElementById("files").onchange = function () {
var reader = new FileReader();
reader.onload = function (e) {
document.getElementById("image").src = e.target.result;
$('#image').show();
};
reader.readAsDataURL(this.files[0]);
};
</script>
<script src="//cdn.jsdelivr.net/npm/sweetalert2@10"></script>
</body>
</html>
โค้ดสำหรับระบบ Login
Code.gs
var ss=
SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1_wnlecA6YK
mzLYw0pEBLqMFDSml6A9_Evc0ZW-HdqiY/edit#gid=0');
function doGet(e) {
var htmlOutput = HtmlService.createTemplateFromFile('Login');
htmlOutput.message = '';
return htmlOutput.evaluate();
}
122
function doPost(e) {
Logger.log(JSON.stringify(e));
if(e.parameter.LoginButton == 'Login')
{
var username = e.parameter.username;
var password = e.parameter.password;
var checkanswer = checkLogin(username, password);
if(checkanswer == 'TRUE')
{
var htmlOutput = HtmlService.createTemplateFromFile('Welcome');
htmlOutput.username = username.toUpperCase();
htmlOutput.message = '';
return htmlOutput.evaluate();
}
else
{
var htmlOutput = HtmlService.createTemplateFromFile('Login');
htmlOutput.message = 'กรอกชื่อผใู้ ชห้ รือรหัสผ่าน';
return htmlOutput.evaluate();
}
}
else if(e.parameter.LogoutButton == 'Logout')
{
LogOutUserNow(e.parameter.username);
var htmlOutput = HtmlService.createTemplateFromFile('Login');
htmlOutput.message = 'ออกจากระบบแล้ว';
return htmlOutput.evaluate();
}
}
function getUrl() {
var url = ScriptApp.getService().getUrl();
return url;
}
function checkLogin(username, password) {
123
var usernamesheet = ss.getSheets()[0]
var currentsheet = ss.getSheets()[1]
var usernameLastRow = usernamesheet.getLastRow();
var currentLastRow = currentsheet.getLastRow();
var found_record = '';
for(var y = 2; y <= currentLastRow; y++)
{
if(currentsheet.getRange(y, 1).getValue().toUpperCase() == username.toUpperCase())
{
found_record = 'TRUE';
var d = new Date();
currentsheet.getRange(y, 2).setValue(d);
}
}
if(found_record == '')
{
for(var i = 2; i <= usernameLastRow; i++)
{
if(usernamesheet.getRange(i, 1).getValue().toUpperCase() ==
username.toUpperCase() &&
usernamesheet.getRange(i, 2).getValue().toUpperCase() == password.toUpperCase())
{
found_record = 'TRUE';
currentsheet.appendRow([username.toUpperCase(), new Date()]);
}
}
}
if(found_record == '')
{
found_record = 'FALSE';
}
return found_record;
}
function LogOutUserNow(username)
124
{
var currentsheet = ss.getSheets()[1]
var currentLastRow = currentsheet.getLastRow();
for(var y = 2; y <= currentLastRow; y++)
{
if(currentsheet.getRange(y, 1).getValue() == username.toUpperCase())
{
currentsheet.getRange(y, 3).setValue('X');
}
}
for(var y = 2; y <= currentLastRow; y++)
{
if(currentsheet.getRange(y, 3).getValue() == 'X')
{
currentsheet.deleteRow(y);
}
}
}
function LogOutUser()
{
var currentsheet = ss.getSheets()[1]
var currentLastRow = currentsheet.getLastRow();
var ThirtyMinutesAgo = new Date( Date.now() - 30000 * 60 );
for(var y = 2; y <= currentLastRow; y++)
{
if(currentsheet.getRange(y, 2).getValue() < ThirtyMinutesAgo)
{
currentsheet.getRange(y, 3).setValue('X');
}
}
for(var y = 2; y <= currentLastRow; y++)
{
if(currentsheet.getRange(y, 3).getValue() == 'X')
{
currentsheet.deleteRow(y);
}
125
}
}
Login.html
<!DOCTYPE html>
<html>
<head>
<script>
</script>
<base target="_top">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.cs
s">
<script
src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"><
/script>
<script type="text/javascript" src="js/materialize.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Prompt">
<style>
body {
font-family: "Prompt";
font-size: 16px;
}
</style>
</head>
<body bgcolor="#FFCC00">
<div class="row">
<div class="col s12 m4 offset-m4">
<div class="card">
<div class="card-action teal lighten-1 #ffd600 yellow accent-4 white-text">
<h3>ลงช่ือเข้าสูร่ ะบบ NTSTOCK </h3>
</div>
<?var url = getUrl();?>
<form method="post" action="<?= url ?>" >
<div class="card-content">
<div class="form-field">
126
<label>UserName</label>
<input type="text" name="username" />
</div><br>
<div class="form-field">
<label>Password</label>
<input type="password" name="password" />
</div><br>
<div class="form-field">
<button class = "btn-large wave-effect #ffd600 yellow accent-4 wave-dark" style =
"width:100%" type="submit" value="Login" name="LoginButton">Login</button>
<span><?= message ?></span>
</div><br>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Welcome.himl
<!DOCTYPE html>
<html>
<head>
<script>
</script>
<base target="_top">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.cs
s">
<script
src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"><
/script>
<script type="text/javascript" src="js/materialize.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Prompt">
127
<style>
body {
font-family: "Prompt";
font-size: 18px;
}
</style>
</head>
<body bgcolor="#FFCC00">
<div class="row">
<div class="col s12 m4 offset-m4">
<div class="card">
<div class="card-action teal lighten-1 yellow accent-4 white-text">
<h3>เข้าสรู่ ะบบเรยี บร้อย</h3>
</div>
<?var url = getUrl();?>
<form method="post" action="<?= url ?>" >
<br><center>
<span style="font-weight: bold">ยินดีตอนรับ <?= username ?></span> </center>
<input type="hidden" value="<?= username ?>" name="username" />
<span><?= message ?></span>
<br><center>
<button class="waves-effect waves-red btn yellow White-text" style = "width:50%"
type="button" onclick="linkweb()">CLICK</button>
</center><br><br>
<button class = "btn-large wave-effect #ffd600 yellow accent-4 wave-dark" style =
"width:100%" type="submit" value="Logout"
name="LogoutButton">Logout</button>
<br>
</form>
</div>
</div>
</div>
<script>
function
linkweb(){window.open("https://script.google.com/macros/s/AKfycbwNbIgwRX-
x906Ax7oNkSGGLgCAWo8aB3-N8StcafY1U7Avy_ix/exec");
128
}
</script>
</body>
</html>
ภาคผนวก จ
โคด้ ระบบเครอ่ื งตรวจรู้คนเดินผา่ น
130
const int Trig = 9;
int Echo = 10;
int speek = 12;
long duration;
int distance;
void setup() {
Serial.begin(9600);
pinMode(speek, OUTPUT);
pinMode(Trig, OUTPUT);
pinMode(Echo, INPUT);
}
void loop() {
digitalWrite(Trig, LOW);
delayMicroseconds(5);
digitalWrite(Trig, HIGH);
delayMicroseconds(10);
digitalWrite(Trig, LOW);
duration = pulseIn(Echo,HIGH);
distance = duration *0.034 / 2;
if (distance <= 30)
{
digitalWrite(speek, HIGH);
}
else
{
digitalWrite (speek, LOW);
}
delay(500);
}
ภาคผนวก ฉ
ลายวงจรพมิ พ์ ดา้ นล่าง และรปู ของวงจรเคร่อื งตรวจร้คู นเดนิ ผา่ น
132
รปู ภาพ ภาคผนวก ฉ ที่ 1 รูปลายวงจรพมิ พ์ด้านลา่ ง
รปู ภาพ ภาคผนวก ฉ ท่ี 2 และรปู ของวงจรเครือ่ งตรวจร้คู นเดินผา่ น
133
ประวตั ิผูเ้ ขยี น
ชือ่ -นามสกลุ นางสาวศิรลิ กั ษณ์ พมิ พ์บงึ
วัน-เดอื น-ปีเกดิ 20 พฤศจิกายน 2542
ท่ีอยู่ 111/1 หมู่ 4 ต.หนองหญ้าปลอ้ ง อ.วังสะพุง จ.เลย 42130
ประวัติการศึกษา
วศบ. วิศวกรรมอเิ ล็กทรอนกิ ส์อัจฉริยะ
ปริญญาตรี คณะวิศวกรรมศาสตร์
มหาวิทยาลยั เทคโนโลยีราชมงคลอสี าน วิทยาเขตขอนแก่น
ปีการศึกษา 2563
ปวส. ช่างอเิ ลก็ ทรอนกิ ส์
มหาวทิ ยาลยั เทคโนโลยีราชมงคลอสี าน วิทยาเขตขอนแก่น
ปกี ารศกึ ษา 2561
ปวช. ชา่ งอเิ ล็กทรอนกิ ส์
วทิ ยาลัยเทคนคิ เลย
ปกี ารศึกษา 2558
134
ประวัตผิ ูเ้ ขียน
ชอ่ื -นามสกุล นายณัฐนันท์ กองลาแซ
วนั -เดอื น-ปเี กดิ 1 พฤศจิกายน 2542
ท่อี ยู่ 126/17 ต.กุดปอ่ ง อ.เมือง จ.เลย 42000
ประวตั ิการศึกษา
วศบ. วศิ วกรรมอิเลก็ ทรอนกิ ส์อัจฉริยะ
ปรญิ ญาตรี คณะวศิ วกรรมศาสตร์
มหาวทิ ยาลยั เทคโนโลยีราชมงคลอีสาน วทิ ยาเขตขอนแกน่
ปีการศกึ ษา 2563
ปวส. ช่างอิเลก็ ทรอนิกส์
มหาวิทยาลัยเทคโนโลยรี าชมงคลอีสาน วทิ ยาเขตขอนแก่น
ปกี ารศกึ ษา 2561
ปวช. ช่างอเิ ลก็ ทรอนกิ ส์
วิทยาลัยเทคนิคเลย
ปกี ารศกึ ษา 2558