L'idea e' che quando viene inserita la chiavetta, viene generato un file sulla chiavetta con all'interno le informazioni di ora e data e viene mandato un segnale acustico e luminoso dell'avvenuta scrittura
Nello schema Fritzing, dato che non ci sono tutti i componenti nella libreria, ho messo un buzzer passivo a due contatti al posto di un buzzer attivo a tre contatti e un RN-41 al posto di CH376S (tanto entrambi hanno una connessione seriale a 4 contatti Vcc/Gnd/Tx/Rx)
Nel dettaglio
D06 = DS1302 SCLK
D07 = DS1302 DATA IO
D08 = DS1302 CE RESET
D09 = Speaker Signal
D10 = CH376S TXD
D11 = CH376S RXD
D13 = led
tutte le alimentazioni a Vcc 5.0 V
i componenti sono
Arduino nano (cinese) : circa 2.5 euro
CH376S (cinese) : circa 3 euro
DS1302 (cinese) : circa 1 euro
buzzer attivo (cinese) : circa 0.5 euro
1 led rosso
1 resistenza 220 Ohm
Circuito di prova (non proprio ordinato) con una Arduino Uno al posto della Nano |
il programma completo e' il seguente (circa 10 Kb compilato)
----------------------------------------------------------------------------------
#include <Wire.h>
#include <SoftwareSerial.h>
// lettore USB
byte computerByte; //used to store data coming from the computer
byte USB_Byte; //used to store data coming from the USB stick
int LED = 13; //the LED is connected to digital pin 13
int timeOut = 2000; //TimeOut is 2 seconds. This is the amount of time you wish to wait for a response from the CH376S module.
SoftwareSerial USB(10, 11); // Digital pin 10 on Arduino (RX) connects to TXD on the CH376S module
// Digital pin 11 on Arduino (TX) connects to RXD on the CH376S module
// GND on Arduino to GND on CH376S module
// 5V on Arduino to 5V on CH376S module
int connessione;
int chiave_presente;
// DT1302
#define DS1302_SCLK_PIN 6 // Arduino pin for the Serial Clock
#define DS1302_IO_PIN 7 // Arduino pin for the Data I/O
#define DS1302_CE_PIN 8 // Arduino pin for the Chip Enable
#define bcd2bin(h,l) (((h)*10) + (l))
#define bin2bcd_h(x) ((x)/10)
#define bin2bcd_l(x) ((x)%10)
#define DS1302_SECONDS 0x80
#define DS1302_MINUTES 0x82
#define DS1302_HOURS 0x84
#define DS1302_DATE 0x86
#define DS1302_MONTH 0x88
#define DS1302_DAY 0x8A
#define DS1302_YEAR 0x8C
#define DS1302_ENABLE 0x8E
#define DS1302_TRICKLE 0x90
#define DS1302_CLOCK_BURST 0xBE
#define DS1302_CLOCK_BURST_WRITE 0xBE
#define DS1302_CLOCK_BURST_READ 0xBF
#define DS1302_RAMSTART 0xC0
#define DS1302_RAMEND 0xFC
#define DS1302_RAM_BURST 0xFE
#define DS1302_RAM_BURST_WRITE 0xFE
#define DS1302_RAM_BURST_READ 0xFF
#define DS1302_D0 0
#define DS1302_D1 1
#define DS1302_D2 2
#define DS1302_D3 3
#define DS1302_D4 4
#define DS1302_D5 5
#define DS1302_D6 6
#define DS1302_D7 7
#define DS1302_READBIT DS1302_D0 // READBIT=1: read instruction
#define DS1302_RC DS1302_D6
#define DS1302_CH DS1302_D7 // 1 = Clock Halt, 0 = start
#define DS1302_AM_PM DS1302_D5 // 0 = AM, 1 = PM
#define DS1302_12_24 DS1302 D7 // 0 = 24 hour, 1 = 12 hour
#define DS1302_WP DS1302_D7 // 1 = Write Protect, 0 = enabled
#define DS1302_ROUT0 DS1302_D0
#define DS1302_ROUT1 DS1302_D1
#define DS1302_DS0 DS1302_D2
#define DS1302_DS1 DS1302_D2
#define DS1302_TCS0 DS1302_D4
#define DS1302_TCS1 DS1302_D5
#define DS1302_TCS2 DS1302_D6
#define DS1302_TCS3 DS1302_D7
typedef struct ds1302_struct
{
uint8_t Seconds:4; // low decimal digit 0-9
uint8_t Seconds10:3; // high decimal digit 0-5
uint8_t CH:1; // CH = Clock Halt
uint8_t Minutes:4;
uint8_t Minutes10:3;
uint8_t reserved1:1;
union
{
struct
{
uint8_t Hour:4;
uint8_t Hour10:2;
uint8_t reserved2:1;
uint8_t hour_12_24:1; // 0 for 24 hour format
} h24;
struct
{
uint8_t Hour:4;
uint8_t Hour10:1;
uint8_t AM_PM:1; // 0 for AM, 1 for PM
uint8_t reserved2:1;
uint8_t hour_12_24:1; // 1 for 12 hour format
} h12;
};
uint8_t Date:4; // Day of month, 1 = first day
uint8_t Date10:2;
uint8_t reserved3:2;
uint8_t Month:4; // Month, 1 = January
uint8_t Month10:1;
uint8_t reserved4:3;
uint8_t Day:3; // Day of week, 1 = first day (any day)
uint8_t reserved5:5;
uint8_t Year:4; // Year, 0 = year 2000
uint8_t Year10:4;
uint8_t reserved6:7;
uint8_t WP:1; // WP = Write Protect
};
// Speaker
int speakerPin = 9;
void playTone(int tone, int duration) {
for (long i = 0; i < duration * 1000L; i += tone * 2) {
digitalWrite(speakerPin, HIGH);
delayMicroseconds(tone);
digitalWrite(speakerPin, LOW);
delayMicroseconds(tone);
}
}
// Fine speaker
void setup()
{
ds1302_struct rtc;
pinMode(speakerPin, OUTPUT);
Serial.begin(9600);
Serial.println(F("Start Puncher"));
//Serial.println(F("Version 2, March 2013"));
USB.begin(9600); // Setup serial communication with the CH376S module (using the default baud rate of 9600)
pinMode(LED,OUTPUT); // Define digital pin 13 as an OUTPUT pin - so that we can use it with an LED
digitalWrite(LED,LOW); // Turn off the LED
DS1302_write (DS1302_ENABLE, 0);
DS1302_write (DS1302_TRICKLE, 0x00);
// Remove the next define,
// after the right date and time are set.
//#define SET_DATE_TIME_JUST_ONCE
#ifdef SET_DATE_TIME_JUST_ONCE
int seconds, minutes, hours, dayofweek, dayofmonth, month, year;
seconds = 0;
minutes = 07;
hours = 10;
dayofweek = 3; // Day of week, any day can be first, counts 1...7
dayofmonth = 26; // Day of month, 1...31
month = 8; // month 1...12
year = 2015;
memset ((char *) &rtc, 0, sizeof(rtc));
rtc.Seconds = bin2bcd_l( seconds);
rtc.Seconds10 = bin2bcd_h( seconds);
rtc.CH = 0; // 1 for Clock Halt, 0 to run;
rtc.Minutes = bin2bcd_l( minutes);
rtc.Minutes10 = bin2bcd_h( minutes);
rtc.h24.Hour = bin2bcd_l( hours);
rtc.h24.Hour10 = bin2bcd_h( hours);
rtc.h24.hour_12_24 = 0; // 0 for 24 hour format
rtc.Date = bin2bcd_l( dayofmonth);
rtc.Date10 = bin2bcd_h( dayofmonth);
rtc.Month = bin2bcd_l( month);
rtc.Month10 = bin2bcd_h( month);
rtc.Day = dayofweek;
rtc.Year = bin2bcd_l( year - 2000);
rtc.Year10 = bin2bcd_h( year - 2000);
rtc.WP = 0;
DS1302_clock_burst_write( (uint8_t *) &rtc);
#endif
}
void loop()
{
ds1302_struct rtc;
char buffer[80]; // the code uses 70 characters.
connessione = 0;
chiave_presente = 0;
checkConnection(0x01);
if (connessione == 1)
{
Serial.println("Connessione Presente");
set_USB_Mode(0x06);
if (chiave_presente == 1)
{
// prende il tempo dall'orologio
DS1302_clock_burst_read( (uint8_t *) &rtc);
sprintf( buffer, "Time = %02d:%02d:%02d, ", \
bcd2bin( rtc.h24.Hour10, rtc.h24.Hour), \
bcd2bin( rtc.Minutes10, rtc.Minutes), \
bcd2bin( rtc.Seconds10, rtc.Seconds));
Serial.println(buffer);
resetALL();
//scrive il file
writeFile("lanterna1.txt", buffer); // emette il suono di conferma
sprintf(buffer, "Date(day of month) = %d, Month = %d, " \
"Day(day of week) = %d, Year = %d", \
bcd2bin( rtc.Date10, rtc.Date), \
bcd2bin( rtc.Month10, rtc.Month), \
rtc.Day, \
2000 + bcd2bin( rtc.Year10, rtc.Year));
Serial.println( buffer);
resetALL();
//scrive il file
appendFile("lanterna1.txt", buffer); // emette il suono di conferma
delay(1000);
playTone(400,100);
blinkLED();
Serial.println("************FINE*************");
}
}
if(USB.available()){ // This is here to capture any unexpected data transmitted by the CH376S module
Serial.print("CH376S has just sent this code:");
Serial.println(USB.read(), HEX);
}
delay(5000);
}
void DS1302_clock_burst_read( uint8_t *p)
{
int i;
_DS1302_start();
_DS1302_togglewrite( DS1302_CLOCK_BURST_READ, true);
for( i=0; i<8; i++)
{
*p++ = _DS1302_toggleread();
}
_DS1302_stop();
}
void DS1302_clock_burst_write( uint8_t *p)
{
int i;
_DS1302_start();
_DS1302_togglewrite( DS1302_CLOCK_BURST_WRITE, false);
for( i=0; i<8; i++)
{
_DS1302_togglewrite( *p++, false);
}
_DS1302_stop();
}
uint8_t DS1302_read(int address)
{
uint8_t data;
bitSet( address, DS1302_READBIT);
_DS1302_start();
_DS1302_togglewrite( address, true);
data = _DS1302_toggleread();
_DS1302_stop();
return (data);
}
void DS1302_write( int address, uint8_t data)
{
bitClear( address, DS1302_READBIT);
_DS1302_start();
_DS1302_togglewrite( address, false);
_DS1302_togglewrite( data, false);
_DS1302_stop();
}
void _DS1302_start( void)
{
digitalWrite( DS1302_CE_PIN, LOW); // default, not enabled
pinMode( DS1302_CE_PIN, OUTPUT);
digitalWrite( DS1302_SCLK_PIN, LOW); // default, clock low
pinMode( DS1302_SCLK_PIN, OUTPUT);
pinMode( DS1302_IO_PIN, OUTPUT);
digitalWrite( DS1302_CE_PIN, HIGH); // start the session
delayMicroseconds( 4); // tCC = 4us
}
void _DS1302_stop(void)
{
digitalWrite( DS1302_CE_PIN, LOW);
delayMicroseconds( 4); // tCWH = 4us
}
uint8_t _DS1302_toggleread( void)
{
uint8_t i, data;
data = 0;
for( i = 0; i <= 7; i++)
{
digitalWrite( DS1302_SCLK_PIN, HIGH);
delayMicroseconds( 1);
digitalWrite( DS1302_SCLK_PIN, LOW);
delayMicroseconds( 1); // tCL=1000ns, tCDD=800ns
bitWrite( data, i, digitalRead( DS1302_IO_PIN));
}
return( data);
}
void _DS1302_togglewrite( uint8_t data, uint8_t release)
{
int i;
for( i = 0; i <= 7; i++)
{
digitalWrite( DS1302_IO_PIN, bitRead(data, i));
delayMicroseconds( 1); // tDC = 200ns
digitalWrite( DS1302_SCLK_PIN, HIGH);
delayMicroseconds( 1); // tCH = 1000ns, tCDH = 800ns
if( release && i == 7)
{
pinMode( DS1302_IO_PIN, INPUT);
}
else
{
digitalWrite( DS1302_SCLK_PIN, LOW);
delayMicroseconds( 1); // tCL=1000ns, tCDD=800ns
}
}
}
// funzioni USB
void checkConnection(byte value){
USB.write(0x57);
USB.write(0xAB);
USB.write(0x06);
USB.write(value);
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.
if(getResponseFromUSB()==(255-value)){
//Serial.println(">Connection to CH376S was successful.");
connessione = 1;
} else {
//Serial.print(">Connection to CH376S - FAILED.");
connessione = 0;
}
}
}
void set_USB_Mode (byte value){
USB.write(0x57);
USB.write(0xAB);
USB.write(0x15);
USB.write(value);
delay(20);
if(USB.available()){
USB_Byte=USB.read();
//Check to see if the command has been successfully transmitted and acknowledged.
if(USB_Byte==0x51){ // If true - the CH376S has acknowledged the command.
//Serial.println("set_USB_Mode command acknowledged"); //The CH376S will now check and monitor the USB port
USB_Byte = USB.read();
//Check to see if the USB stick is connected or not.
if(USB_Byte==0x15){ // If true - there is a USB stick connected
//Serial.println("USB is present");
chiave_presente = 1;
blinkLED(); // If the process was successful, then turn the LED on for 1 second
} else {
chiave_presente = 0;
//Serial.print("USB Not present. Error code:"); // If the USB is not connected - it should return an Error code = FFH
//Serial.print(USB_Byte, HEX);
//Serial.println("H");
}
} else {
//Serial.print("CH3765 error! Error code:");
//Serial.print(USB_Byte, HEX);
//Serial.println("H");
chiave_presente = 0;
}
}
delay(20);
}
//resetALL=========================================================================================
//This will perform a hardware reset of the CH376S module - which usually takes about 35 msecs =====
void resetALL(){
USB.write(0x57);
USB.write(0xAB);
USB.write(0x05);
//Serial.println("The CH376S module has been reset !");
delay(200);
}
void writeFile(String fileName, String data){
resetALL(); //Reset the module
set_USB_Mode(0x06); //Set to USB Mode
diskConnectionStatus(); //Check that communication with the USB device is possible
USBdiskMount(); //Prepare the USB for reading/writing - you need to mount the USB disk for proper read/write operations.
setFileName(fileName); //Set File name
if(fileCreate()){ //Try to create a new file. If file creation is successful
fileWrite(data); //write data to the file.
} else {
Serial.println("File could not be created, or it already exists");
}
fileClose(0x01);
}
void setFileName(String fileName){
Serial.print("Setting filename to:");
Serial.println(fileName);
USB.write(0x57);
USB.write(0xAB);
USB.write(0x2F);
USB.write(0x2F); // Every filename must have this byte to indicate the start of the file name.
USB.print(fileName); // "fileName" is a variable that holds the name of the file. eg. TEST.TXT
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.
delay(20);
}
void diskConnectionStatus(){
USB.write(0x57);
USB.write(0xAB);
USB.write(0x30);
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.
if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
} else {
}
}
}
void USBdiskMount(){
Serial.println("Mounting USB disk");
USB.write(0x57);
USB.write(0xAB);
USB.write(0x31);
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.
if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
} else {
}
}
}
void fileOpen(){
Serial.println("Opening file.");
USB.write(0x57);
USB.write(0xAB);
USB.write(0x32);
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.
if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
} else {
}
}
}
//setByteRead=====================================================================================
//This function is required if you want to read data from the file.
boolean setByteRead(byte numBytes){
boolean bytesToRead=false;
int timeCounter = 0;
USB.write(0x57);
USB.write(0xAB);
USB.write(0x3A);
USB.write((byte)numBytes); //tells the CH376S how many bytes to read at a time
USB.write((byte)0x00);
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.
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.
bytesToRead=true;
}
}
return(bytesToRead);
}
//getFileSize()===================================================================================
//writes the file size to the serial Monitor.
int getFileSize(){
int fileSize=0;
Serial.println("Getting File Size");
USB.write(0x57);
USB.write(0xAB);
USB.write(0x0C);
USB.write(0x68);
delay(100);
Serial.print("FileSize =");
if(USB.available()){
fileSize = fileSize + USB.read();
}
if(USB.available()){
fileSize = fileSize + (USB.read()*255);
}
if(USB.available()){
fileSize = fileSize + (USB.read()*255*255);
}
if(USB.available()){
fileSize = fileSize + (USB.read()*255*255*255);
}
Serial.println(fileSize);
delay(10);
return(fileSize);
}
//fileRead========================================================================================
//read the contents of the file
void fileRead(){
Serial.println("Reading file:");
byte firstByte = 0x00; //Variable to hold the firstByte from every transmission. Can be used as a checkSum if required.
byte numBytes = 0x40; //The maximum value is 0x40 = 64 bytes
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.
USB.write(0x57);
USB.write(0xAB);
USB.write(0x27); //Command to read ALL of the bytes (allocated by setByteRead(x))
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.
firstByte=USB.read(); //Read the first byte
while(USB.available()){
Serial.write(USB.read()); //Send the data from the USB disk to the Serial monitor
delay(1); //This delay is necessary for successful Serial transmission
}
}
if(!continueRead()){ //prepares the module for further reading. If false, stop reading.
break; //You need the continueRead() method if the data to be read from the USB device is greater than numBytes.
}
}
Serial.println();
Serial.println("NO MORE DATA");
}
//fileWrite=======================================================================================
//are the commands used to write to the file
void fileWrite(String data){
Serial.println("Writing to file:");
byte dataLength = (byte) data.length(); // This variable holds the length of the data to be written (in bytes)
Serial.println(data);
Serial.print("Data Length:");
Serial.println(dataLength);
delay(100);
// This set of commands tells the CH376S module how many bytes to expect from the Arduino. (defined by the "dataLength" variable)
USB.write(0x57);
USB.write(0xAB);
USB.write(0x3C);
USB.write((byte) dataLength);
USB.write((byte) 0x00);
if(waitForResponse("setting data Length")){ // Wait for an acknowledgement from the CH376S module before trying to send data to it
if(getResponseFromUSB()==0x1E){ // 0x1E indicates that the USB device is in write mode.
USB.write(0x57);
USB.write(0xAB);
USB.write(0x2D);
USB.print(data); // write the data to the file
if(waitForResponse("writing data to file")){ // wait for an acknowledgement from the CH376S module
}
Serial.print("Write code (normally FF and 14): ");
Serial.print(USB.read(),HEX); // code is normally 0xFF
Serial.print(",");
USB.write(0x57);
USB.write(0xAB);
USB.write(0x3D); // This is used to update the file size. Not sure if this is necessary for successful writing.
if(waitForResponse("updating file size")){ // wait for an acknowledgement from the CH376S module
}
Serial.println(USB.read(),HEX); //code is normally 0x14
}
}
}
//appendFile()====================================================================================
//is used to write data to the end of the file, without erasing the contents of the file.
void appendFile(String fileName, String data){
resetALL(); //Reset the module
set_USB_Mode(0x06); //Set to USB Mode
diskConnectionStatus(); //Check that communication with the USB device is possible
USBdiskMount(); //Prepare the USB for reading/writing - you need to mount the USB disk for proper read/write operations.
setFileName(fileName); //Set File name
fileOpen(); //Open the file
filePointer(false); //filePointer(false) is to set the pointer at the end of the file. filePointer(true) will set the pointer to the beginning.
fileWrite(data); //Write data to the end of the file
fileClose(0x01); //Close the file using 0x01 - which means to update the size of the file on close.
}
//continueRead()==================================================================================
//continue to read the file : I could not get this function to work as intended.
boolean continueRead(){
boolean readAgain = false;
USB.write(0x57);
USB.write(0xAB);
USB.write(0x3B);
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.
if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
readAgain=true;
}
}
return(readAgain);
}
//fileCreate()========================================================================================
//the command sequence to create a file
boolean fileCreate(){
boolean createdFile = false;
USB.write(0x57);
USB.write(0xAB);
USB.write(0x34);
if(waitForResponse("creating file")){ //wait for a response from the CH376S. If file has been created successfully, it will return true.
if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
createdFile=true;
}
}
return(createdFile);
}
//fileDelete()========================================================================================
//the command sequence to delete a file
void fileDelete(String fileName){
setFileName(fileName);
delay(20);
USB.write(0x57);
USB.write(0xAB);
USB.write(0x35);
if(waitForResponse("deleting file")){ //wait for a response from the CH376S. If file has been created successfully, it will return true.
if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
Serial.println("Successfully deleted file");
}
}
}
//filePointer========================================================================================
//is used to set the file pointer position. true for beginning of file, false for the end of the file.
void filePointer(boolean fileBeginning){
USB.write(0x57);
USB.write(0xAB);
USB.write(0x39);
if(fileBeginning){
USB.write((byte)0x00); //beginning of file
USB.write((byte)0x00);
USB.write((byte)0x00);
USB.write((byte)0x00);
} else {
USB.write((byte)0xFF); //end of file
USB.write((byte)0xFF);
USB.write((byte)0xFF);
USB.write((byte)0xFF);
}
if(waitForResponse("setting file pointer")){ //wait for a response from the CH376S.
if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful
Serial.println("Pointer successfully applied");
}
}
}
//fileClose=======================================================================================
//closes the file
void fileClose(byte closeCmd){
Serial.println("Closing file:");
USB.write(0x57);
USB.write(0xAB);
USB.write(0x36);
USB.write((byte)closeCmd); // closeCmd = 0x00 = close without updating file Size, 0x01 = close and update file Size
if(waitForResponse("closing file")){ // wait for a response from the CH376S.
byte resp = getResponseFromUSB();
if(resp==0x14){ // CH376S will send 0x14 if this command was successful
Serial.println(">File closed successfully.");
} else {
Serial.print(">Failed to close file. Error code:");
Serial.println(resp, HEX);
}
}
}
//waitForResponse===================================================================================
//is used to wait for a response from USB. Returns true when bytes become available, false if it times out.
boolean waitForResponse(String errorMsg){
boolean bytesAvailable = true;
int counter=0;
while(!USB.available()){ //wait for CH376S to verify command
delay(1);
counter++;
if(counter>timeOut){
Serial.print("TimeOut waiting for response: Error while: ");
Serial.println(errorMsg);
bytesAvailable = false;
break;
}
}
delay(1);
return(bytesAvailable);
}
//getResponseFromUSB================================================================================
//is used to get any error codes or messages from the CH376S module (in response to certain commands)
byte getResponseFromUSB(){
byte response = byte(0x00);
if (USB.available()){
response = USB.read();
}
return(response);
}
//blinkLED==========================================================================================
//Turn an LED on for 1 second
void blinkLED(){
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED,LOW);
}
Nessun commento:
Posta un commento