· 6 years ago · Aug 22, 2019, 10:24 PM
1/* ===============================================================
2 Project: CH376S USB Read/Write Module testing ground
3 Author: Scott C
4 Created: 1st May 2015
5 Arduino IDE: 1.6.2
6 Website: http://arduinobasics.blogspot.com/p/arduino-basics-projects-page.html
7 Description: This project will allow you to perform many of the functions available on the CH376S module.
8 Checking connection to the module, putting the module into USB mode, resetting the module,
9 reading, writing, appending text to files on the USB stick. This is very useful alternative to
10 SD card modules, plus it doesn't need any libraries.
11================================================================== */
12
13#include <SoftwareSerial.h>
14
15byte computerByte; //used to store data coming from the computer
16byte USB_Byte; //used to store data coming from the USB stick
17int LED = 13; //the LED is connected to digital pin 13
18int timeOut = 2000; //TimeOut is 2 seconds. This is the amount of time you wish to wait for a response from the CH376S module.
19String wrData = "What is the meaning of life ?"; //We will write this data to a newly created file.
20String wrData2 = "42"; //We will append this data to an already existing file.
21
22SoftwareSerial USB(10, 11); // Digital pin 10 on Arduino (RX) connects to TXD on the CH376S module
23 // Digital pin 11 on Arduino (TX) connects to RXD on the CH376S module
24 // GND on Arduino to GND on CH376S module
25 // 5V on Arduino to 5V on CH376S module
26//==============================================================================================================================================
27void setup() {
28 Serial.begin(9600); // Setup serial communication with the computer (using a baud rate of 9600 on serial monitor)
29 USB.begin(9600); // Setup serial communication with the CH376S module (using the default baud rate of 9600)
30 pinMode(LED,OUTPUT); // Define digital pin 13 as an OUTPUT pin - so that we can use it with an LED
31 digitalWrite(LED,LOW); // Turn off the LED
32}
33
34//================================================================================================================================================
35void loop() {
36 if(Serial.available()){
37 computerByte = Serial.read(); //read any incoming bytes from the Serial monitor, and store this byte in the variable called computerByte
38 if(computerByte==49){ //1 //If you send the number 1 from the serial monitor, the arduino will read it as digital number 49. Google "ascii table" for more info.
39 printCommandHeader("COMMAND1: CHECK CONNECTION");
40 checkConnection(0x01); // Check for successful connection and communication with the CH376S module.
41 }
42 if(computerByte==50){ //2
43 printCommandHeader("COMMAND2: set_USB_Mode");
44 set_USB_Mode(0x06); // Code used to enable read/write communication and monitoring of the USB stick
45 }
46 if(computerByte==51){ //3
47 printCommandHeader("COMMAND3: resetALL");
48 resetALL(); // Reset the USB device
49 }
50 if(computerByte==52){ //4
51 printCommandHeader("COMMAND4: Create and Write to File : TEST4.TXT");
52 writeFile("TEST4.TXT", wrData); // Create a file called TEST4.TXT and then Write the contents of wrData to this file
53 }
54 if(computerByte==53){ //5
55 printCommandHeader("COMMAND5: Read File: TEST4.TXT");
56 readFile("TEST4.TXT"); // Read the contents of this file on the USB disk, and display contents in the Serial Monitor
57 }
58 if(computerByte==54){ //6
59 printCommandHeader("COMMAND6: Append data to file: TEST4.TXT");
60 appendFile("TEST4.TXT", wrData2); // Append data to the end of the file.
61 }
62 if(computerByte==55){ //7
63 printCommandHeader("COMMAND7: Delete File: TEST4.TXT");
64 fileDelete("TEST4.TXT"); // Delete the file named TEST4.TXT
65 }
66 if(computerByte==56){ //8
67 printCommandHeader("COMMAND8: Read File: TEST2.TXT");
68 readFile("TEST2.TXT"); // Read the contents of the TEST2.TXT file on the USB disk, and display contents in the Serial Monitor
69 }
70 if(computerByte==57){ //9
71 printCommandHeader("COMMAND9: Read File: TEST3.TXT");
72 readFile("TEST3.TXT"); // Read the contents of the TEST3.TXT file on the USB disk, and display contents in the Serial Monitor
73 }
74 }
75
76 if(USB.available()){ // This is here to capture any unexpected data transmitted by the CH376S module
77 Serial.print("CH376S has just sent this code:");
78 Serial.println(USB.read(), HEX);
79 }
80}
81
82//END OF LOOP FUNCTION ========================================================================================================================================
83
84//print Command header
85void printCommandHeader(String header){
86 Serial.println("======================");
87 Serial.println("");
88 Serial.println(header);
89 Serial.println("----------------------");
90}
91
92//checkConnection==================================================================================
93//This function is used to check for successful communication with the CH376S module. This is not dependant of the presence of a USB stick.
94//Send any value between 0 to 255, and the CH376S module will return a number = 255 - value.
95void checkConnection(byte value){
96 USB.write(0x57);
97 USB.write(0xAB);
98 USB.write(0x06);
99 USB.write(value);
100
101 if(waitForResponse("checking connection")){ //wait for a response from the CH376S. If CH376S responds, it will be true. If it times out, it will be false.
102 if(getResponseFromUSB()==(255-value)){
103 Serial.println(">Connection to CH376S was successful.");
104 blinkLED(); //blink the LED for 1 second if the connection was successful
105 } else {
106 Serial.print(">Connection to CH376S - FAILED.");
107 }
108 }
109}
110
111//set_USB_Mode=====================================================================================
112//Make sure that the USB is inserted when using 0x06 as the value in this specific code sequence
113void set_USB_Mode (byte value){
114 USB.write(0x57);
115 USB.write(0xAB);
116 USB.write(0x15);
117 USB.write(value);
118
119 delay(20);
120
121 if(USB.available()){
122 USB_Byte=USB.read();
123 //Check to see if the command has been successfully transmitted and acknowledged.
124 if(USB_Byte==0x51){ // If true - the CH376S has acknowledged the command.
125 Serial.println("set_USB_Mode command acknowledged"); //The CH376S will now check and monitor the USB port
126 USB_Byte = USB.read();
127
128 //Check to see if the USB stick is connected or not.
129 if(USB_Byte==0x15){ // If true - there is a USB stick connected
130 Serial.println("USB is present");
131 blinkLED(); // If the process was successful, then turn the LED on for 1 second
132 } else {
133 Serial.print("USB Not present. Error code:"); // If the USB is not connected - it should return an Error code = FFH
134 Serial.print(USB_Byte, HEX);
135 Serial.println("H");
136 }
137
138 } else {
139 Serial.print("CH3765 error! Error code:");
140 Serial.print(USB_Byte, HEX);
141 Serial.println("H");
142 }
143 }
144 delay(20);
145}
146
147//resetALL=========================================================================================
148//This will perform a hardware reset of the CH376S module - which usually takes about 35 msecs =====
149void resetALL(){
150 USB.write(0x57);
151 USB.write(0xAB);
152 USB.write(0x05);
153 Serial.println("The CH376S module has been reset !");
154 delay(200);
155}
156
157//readFile=====================================================================================
158//This will send a series of commands to read data from a specific file (defined by fileName)
159void readFile(String fileName){
160 resetALL(); //Reset the module
161 set_USB_Mode(0x06); //Set to USB Mode
162 diskConnectionStatus(); //Check that communication with the USB device is possible
163 USBdiskMount(); //Prepare the USB for reading/writing - you need to mount the USB disk for proper read/write operations.
164 setFileName(fileName); //Set File name
165 fileOpen(); //Open the file for reading
166 int fs = getFileSize(); //Get the size of the file
167 fileRead(); //***** Send the command to read the file ***
168 fileClose(0x00); //Close the file
169}
170
171//writeFile========================================================================================
172//is used to create a new file and then write data to that file. "fileName" is a variable used to hold the name of the file (e.g TEST.TXT). "data" should not be greater than 255 bytes long.
173void writeFile(String fileName, String data){
174 resetALL(); //Reset the module
175 set_USB_Mode(0x06); //Set to USB Mode
176 diskConnectionStatus(); //Check that communication with the USB device is possible
177 USBdiskMount(); //Prepare the USB for reading/writing - you need to mount the USB disk for proper read/write operations.
178 setFileName(fileName); //Set File name
179 if(fileCreate()){ //Try to create a new file. If file creation is successful
180 fileWrite(data); //write data to the file.
181 } else {
182 Serial.println("File could not be created, or it already exists");
183 }
184 fileClose(0x01);
185}
186
187//appendFile()====================================================================================
188//is used to write data to the end of the file, without erasing the contents of the file.
189void appendFile(String fileName, String data){
190 resetALL(); //Reset the module
191 set_USB_Mode(0x06); //Set to USB Mode
192 diskConnectionStatus(); //Check that communication with the USB device is possible
193 USBdiskMount(); //Prepare the USB for reading/writing - you need to mount the USB disk for proper read/write operations.
194 setFileName(fileName); //Set File name
195 fileOpen(); //Open the file
196 filePointer(false); //filePointer(false) is to set the pointer at the end of the file. filePointer(true) will set the pointer to the beginning.
197 fileWrite(data); //Write data to the end of the file
198 fileClose(0x01); //Close the file using 0x01 - which means to update the size of the file on close.
199}
200
201//setFileName======================================================================================
202//This sets the name of the file to work with
203void setFileName(String fileName){
204 Serial.print("Setting filename to:");
205 Serial.println(fileName);
206 USB.write(0x57);
207 USB.write(0xAB);
208 USB.write(0x2F);
209 USB.write(0x2F); // Every filename must have this byte to indicate the start of the file name.
210 USB.print(fileName); // "fileName" is a variable that holds the name of the file. eg. TEST.TXT
211 USB.write((byte)0x00); // you need to cast as a byte - otherwise it will not compile. The null byte indicates the end of the file name.
212 delay(20);
213}
214
215//diskConnectionStatus================================================================================
216//Check the disk connection status
217void diskConnectionStatus(){
218 Serial.println("Checking USB disk connection status");
219 USB.write(0x57);
220 USB.write(0xAB);
221 USB.write(0x30);
222
223 if(waitForResponse("Connecting to USB disk")){ //wait for a response from the CH376S. If CH376S responds, it will be true. If it times out, it will be false.
224 if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
225 Serial.println(">Connection to USB OK");
226 } else {
227 Serial.print(">Connection to USB - FAILED.");
228 }
229 }
230}
231
232//USBdiskMount========================================================================================
233//initialise the USB disk and check that it is ready - this process is required if you want to find the manufacturing information of the USB disk
234void USBdiskMount(){
235 Serial.println("Mounting USB disk");
236 USB.write(0x57);
237 USB.write(0xAB);
238 USB.write(0x31);
239
240 if(waitForResponse("mounting USB disk")){ //wait for a response from the CH376S. If CH376S responds, it will be true. If it times out, it will be false.
241 if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
242 Serial.println(">USB Mounted - OK");
243 } else {
244 Serial.print(">Failed to Mount USB disk.");
245 }
246 }
247}
248
249//fileOpen========================================================================================
250//opens the file for reading or writing
251void fileOpen(){
252 Serial.println("Opening file.");
253 USB.write(0x57);
254 USB.write(0xAB);
255 USB.write(0x32);
256 if(waitForResponse("file Open")){ //wait for a response from the CH376S. If CH376S responds, it will be true. If it times out, it will be false.
257 if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
258 Serial.println(">File opened successfully.");
259 } else {
260 Serial.print(">Failed to open file.");
261 }
262 }
263}
264
265//setByteRead=====================================================================================
266//This function is required if you want to read data from the file.
267boolean setByteRead(byte numBytes){
268 boolean bytesToRead=false;
269 int timeCounter = 0;
270 USB.write(0x57);
271 USB.write(0xAB);
272 USB.write(0x3A);
273 USB.write((byte)numBytes); //tells the CH376S how many bytes to read at a time
274 USB.write((byte)0x00);
275 if(waitForResponse("setByteRead")){ //wait for a response from the CH376S. If CH376S responds, it will be true. If it times out, it will be false.
276 if(getResponseFromUSB()==0x1D){ //read the CH376S message. If equal to 0x1D, data is present, so return true. Will return 0x14 if no data is present.
277 bytesToRead=true;
278 }
279 }
280 return(bytesToRead);
281}
282
283//getFileSize()===================================================================================
284//writes the file size to the serial Monitor.
285int getFileSize(){
286 int fileSize=0;
287 Serial.println("Getting File Size");
288 USB.write(0x57);
289 USB.write(0xAB);
290 USB.write(0x0C);
291 USB.write(0x68);
292 delay(100);
293 Serial.print("FileSize =");
294 if(USB.available()){
295 fileSize = fileSize + USB.read();
296 }
297 if(USB.available()){
298 fileSize = fileSize + (USB.read()*255);
299 }
300 if(USB.available()){
301 fileSize = fileSize + (USB.read()*255*255);
302 }
303 if(USB.available()){
304 fileSize = fileSize + (USB.read()*255*255*255);
305 }
306 Serial.println(fileSize);
307 delay(10);
308 return(fileSize);
309}
310
311
312//fileRead========================================================================================
313//read the contents of the file
314void fileRead(){
315 Serial.println("Reading file:");
316 byte firstByte = 0x00; //Variable to hold the firstByte from every transmission. Can be used as a checkSum if required.
317 byte numBytes = 0x40; //The maximum value is 0x40 = 64 bytes
318
319 while(setByteRead(numBytes)){ //This tells the CH376S module how many bytes to read on the next reading step. In this example, we will read 0x10 bytes at a time. Returns true if there are bytes to read, false if there are no more bytes to read.
320 USB.write(0x57);
321 USB.write(0xAB);
322 USB.write(0x27); //Command to read ALL of the bytes (allocated by setByteRead(x))
323 if(waitForResponse("reading data")){ //Wait for the CH376S module to return data. TimeOut will return false. If data is being transmitted, it will return true.
324 firstByte=USB.read(); //Read the first byte
325 while(USB.available()){
326 Serial.write(USB.read()); //Send the data from the USB disk to the Serial monitor
327 delay(1); //This delay is necessary for successful Serial transmission
328 }
329 }
330 if(!continueRead()){ //prepares the module for further reading. If false, stop reading.
331 break; //You need the continueRead() method if the data to be read from the USB device is greater than numBytes.
332 }
333 }
334 Serial.println();
335 Serial.println("NO MORE DATA");
336}
337
338//fileWrite=======================================================================================
339//are the commands used to write to the file
340void fileWrite(String data){
341 Serial.println("Writing to file:");
342 byte dataLength = (byte) data.length(); // This variable holds the length of the data to be written (in bytes)
343 Serial.println(data);
344 Serial.print("Data Length:");
345 Serial.println(dataLength);
346 delay(100);
347 // This set of commands tells the CH376S module how many bytes to expect from the Arduino. (defined by the "dataLength" variable)
348 USB.write(0x57);
349 USB.write(0xAB);
350 USB.write(0x3C);
351 USB.write((byte) dataLength);
352 USB.write((byte) 0x00);
353 if(waitForResponse("setting data Length")){ // Wait for an acknowledgement from the CH376S module before trying to send data to it
354 if(getResponseFromUSB()==0x1E){ // 0x1E indicates that the USB device is in write mode.
355 USB.write(0x57);
356 USB.write(0xAB);
357 USB.write(0x2D);
358 USB.print(data); // write the data to the file
359
360 if(waitForResponse("writing data to file")){ // wait for an acknowledgement from the CH376S module
361 }
362 Serial.print("Write code (normally FF and 14): ");
363 Serial.print(USB.read(),HEX); // code is normally 0xFF
364 Serial.print(",");
365 USB.write(0x57);
366 USB.write(0xAB);
367 USB.write(0x3D); // This is used to update the file size. Not sure if this is necessary for successful writing.
368 if(waitForResponse("updating file size")){ // wait for an acknowledgement from the CH376S module
369 }
370 Serial.println(USB.read(),HEX); //code is normally 0x14
371 }
372 }
373}
374
375//continueRead()==================================================================================
376//continue to read the file : I could not get this function to work as intended.
377boolean continueRead(){
378 boolean readAgain = false;
379 USB.write(0x57);
380 USB.write(0xAB);
381 USB.write(0x3B);
382 if(waitForResponse("continueRead")){ //wait for a response from the CH376S. If CH376S responds, it will be true. If it times out, it will be false.
383 if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
384 readAgain=true;
385 }
386 }
387 return(readAgain);
388}
389
390//fileCreate()========================================================================================
391//the command sequence to create a file
392boolean fileCreate(){
393 boolean createdFile = false;
394 USB.write(0x57);
395 USB.write(0xAB);
396 USB.write(0x34);
397 if(waitForResponse("creating file")){ //wait for a response from the CH376S. If file has been created successfully, it will return true.
398 if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
399 createdFile=true;
400 }
401 }
402 return(createdFile);
403}
404
405
406//fileDelete()========================================================================================
407//the command sequence to delete a file
408void fileDelete(String fileName){
409 setFileName(fileName);
410 delay(20);
411 USB.write(0x57);
412 USB.write(0xAB);
413 USB.write(0x35);
414 if(waitForResponse("deleting file")){ //wait for a response from the CH376S. If file has been created successfully, it will return true.
415 if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
416 Serial.println("Successfully deleted file");
417 }
418 }
419}
420
421
422//filePointer========================================================================================
423//is used to set the file pointer position. true for beginning of file, false for the end of the file.
424void filePointer(boolean fileBeginning){
425 USB.write(0x57);
426 USB.write(0xAB);
427 USB.write(0x39);
428 if(fileBeginning){
429 USB.write((byte)0x00); //beginning of file
430 USB.write((byte)0x00);
431 USB.write((byte)0x00);
432 USB.write((byte)0x00);
433 } else {
434 USB.write((byte)0xFF); //end of file
435 USB.write((byte)0xFF);
436 USB.write((byte)0xFF);
437 USB.write((byte)0xFF);
438 }
439 if(waitForResponse("setting file pointer")){ //wait for a response from the CH376S.
440 if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
441 Serial.println("Pointer successfully applied");
442 }
443 }
444}
445
446
447//fileClose=======================================================================================
448//closes the file
449void fileClose(byte closeCmd){
450 Serial.println("Closing file:");
451 USB.write(0x57);
452 USB.write(0xAB);
453 USB.write(0x36);
454 USB.write((byte)closeCmd); // closeCmd = 0x00 = close without updating file Size, 0x01 = close and update file Size
455
456 if(waitForResponse("closing file")){ // wait for a response from the CH376S.
457 byte resp = getResponseFromUSB();
458 if(resp==0x14){ // CH376S will send 0x14 if this command was successful
459 Serial.println(">File closed successfully.");
460 } else {
461 Serial.print(">Failed to close file. Error code:");
462 Serial.println(resp, HEX);
463 }
464 }
465}
466
467//waitForResponse===================================================================================
468//is used to wait for a response from USB. Returns true when bytes become available, false if it times out.
469boolean waitForResponse(String errorMsg){
470 boolean bytesAvailable = true;
471 int counter=0;
472 while(!USB.available()){ //wait for CH376S to verify command
473 delay(1);
474 counter++;
475 if(counter>timeOut){
476 Serial.print("TimeOut waiting for response: Error while: ");
477 Serial.println(errorMsg);
478 bytesAvailable = false;
479 break;
480 }
481 }
482 delay(1);
483 return(bytesAvailable);
484}
485
486//getResponseFromUSB================================================================================
487//is used to get any error codes or messages from the CH376S module (in response to certain commands)
488byte getResponseFromUSB(){
489 byte response = byte(0x00);
490 if (USB.available()){
491 response = USB.read();
492 }
493 return(response);
494}
495
496
497
498//blinkLED==========================================================================================
499//Turn an LED on for 1 second
500void blinkLED(){
501 digitalWrite(LED, HIGH);
502 delay(1000);
503 digitalWrite(LED,LOW);
504}