//Pin connected to ST_CP of 74HC595
int latchPin = 6;
//Pin connected to SH_CP of 74HC595
int clockPin = 13;
////Pin connected to DS of 74HC595
int dataPin = 11;
byte FirstByte;
byte SecondByte;
byte ThirdByte;
byte FourthByte;
byte FifthByte;
int val;
byte serialInArray[5]; // array for storing 3 bytes as they arrive from processing
int serialCount = 0; // for counting the number of bytes received
void setup() {
//Start Serial for debuging purposes
Serial.begin(9600);
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
}
void loop() {
if (Serial.available() > 0){
serialInArray[serialCount] = Serial.read(); // read a byte sent by processing
serialCount++; // increment number of bytes received
if (serialCount > 4 ) { // when 3 bytes received
FirstByte = serialInArray[0]; // get value for Red LEDs
SecondByte = serialInArray[1]; // get value for Green LEDs
ThirdByte = serialInArray[2];
FourthByte = serialInArray[3];
FifthByte = serialInArray[4];
Serial.print(FirstByte);
Serial.print(SecondByte);
Serial.print(ThirdByte);
Serial.print(FourthByte);
Serial.print(FifthByte);
Serial.println("");
//count up routine
digitalWrite(latchPin, 0);
//count up on GREEN LEDs
//count down on RED LEDs
shiftOut(dataPin, clockPin, FirstByte);
shiftOut(dataPin, clockPin, SecondByte);
shiftOut(dataPin, clockPin, ThirdByte);
shiftOut(dataPin, clockPin, FourthByte);
shiftOut(dataPin, clockPin, FifthByte);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(latchPin, 1);
serialCount = 0;
delay(20);
}
}
}
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low
//internal function setup
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
//clear everything out just in case to
//prepare shift register for bit shifting
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
//for each bit in the byte myDataOut�
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--) {
digitalWrite(myClockPin, 0);
//if the value passed to myDataOut and a bitmask result
// true then... so if we are at i=6 and our value is
// %11010100 it would the code compares it to %01000000
// and proceeds to set pinState to 1.
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
//Sets the pin to HIGH or LOW depending on pinState
digitalWrite(myDataPin, pinState);
//register shifts bits on upstroke of clock pin
digitalWrite(myClockPin, 1);
//zero the data pin after shift to prevent bleed through
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
}
To record every time you send something, in the transfer log, you also store it in the SD card, along with the value you sent in milli.
Then to run the reading from the SD card the value of bytes and milliseconds. Then wait until the time is milliseconds minus milliseconds when the playback matches started or greater than the milli value you read from the SD card, then write the byte into the shift register.
في المنتدى الناطق باللغة الإنجليزية ، يجب أن تكتب باللغة الإنجليزية أو تستخدم مترجم جوجل
In the English-speaking forum you should write in English or use google-translate
best regards Stefan
To start of with, you have related information, the timestamp (nillis()) and the 5 databytes. In that case you should use a struct or a class; they are like a record in a phone book where you have a name and a phone number. Below uses a struct that I called PATTERN.
struct PATTERN
{
uint32_t timestamp;
uint8_t data[5];
};
timestamp will contain the value of millis(), data replaces your serialInArray.
And we declare a variable of this new type
PATTERN pattern;
You can use something like
pattern.timestamp = millis();
pattern.data[0] = 0x00;
pattern.data[1] = 0x33;
...
to set the fields in the struct and use siomething like
Serial.print("Timestamp = ");
Serial.println(pattern.timestamp);
to use the fields.
Note:
You will need to install the SdFat library
In setup(), we will initialise the SD card and create a file if it does not yet exists. If the file already exists, it will read it and show the contents.
// https://forum.arduino.cc/t/sd-card-reading-char-of-string-from-serial-port-and-writing-in-shift-register/985401
#include <SPI.h>
#include "SdFat.h"
#include "sdios.h"
// SD card chip select pin. Adjusted for ProMicro setup with CS on A0
const uint8_t chipSelect = A0;
//------------------------------------------------------------------------------
struct PATTERN
{
uint32_t timestamp;
uint8_t data[5];
};
PATTERN pattern;
// File system object.
SdFat sd;
// Use for file creation in folders.
SdFile file;
char filename[13] = "985401.bin";
void setup()
{
Serial.begin(115200);
while (!Serial);
// initialise SD card
if (!sd.begin(chipSelect, SD_SCK_MHZ(50)))
{
sd.initErrorHalt();
}
else
{
Serial.println(F("SD.begin() succeeded"));
}
// if our file exists
if (sd.exists(filename))
{
Serial.print(F("File "));
Serial.print(filename);
Serial.println(F(" exists, opening"));
// read a 'record' from thefile
while (ReadPatternFromFile() == true)
{
// and display it
ShowPattern();
}
}
// if our file does not exist
else
{
Serial.print(F("File "));
Serial.print(filename);
Serial.println(F(" does not exist; creating"));
if (!file.open(filename, O_WRONLY | O_CREAT))
{
Serial.print(F("Error creating file "));
Serial.print(filename);
Serial.println();
// hang forever
for (;;);
}
else
{
Serial.print(F("File "));
Serial.print(filename);
Serial.println(F(" created"));
file.close();
}
}
}
ReadPatternFromFile() will read one record from the file and ShowPattern() will display the contents or run your playback. This comes later.
I've modified your loop() to make use of pattern.
void loop()
{
static bool recordMode = true;
static int serialCount = 0; // for counting the number of bytes received
if (Serial.available() > 0)
{
pattern.data[serialCount] = Serial.read(); // read a byte sent by processing
serialCount++; // increment number of bytes received
if (serialCount > 4 )
{
serialCount = 0;
pattern.timestamp = millis();
ShowPattern();
WritePatternToFile();
}
}
}
As mentioned earlier, data replaces your serialInArray so the receiveddata is directly stored in pattern. Once you have received more than 4 bytes, the timestamp will be set.
ShowPattern() will show the pattern that was received, WritePatternToFile() will save the the specified file.
ShowPattern currently only shows the fields in pattern; you can later modify this to make use of your shift registers
void ShowPattern()
{
Serial.println(F("Pattern:"));
Serial.print(F("\tTimestamp = 0x"));
Serial.print(pattern.timestamp, HEX);
Serial.print(F(", "));
Serial.println((pattern.timestamp));
Serial.print(F("\t"));
for (uint8_t cnt = 0; cnt < sizeof(pattern.data); cnt++)
{
if (pattern.data[cnt] < 0x10)
{
Serial.print(F("0"));
}
Serial.print(pattern.data[cnt], HEX);
Serial.print(F(" "));
}
Serial.println();
}
WritePatternToFile appends (!!) a pattern to a file
/*
append pattern to file
Returns:
false on file open error, true on success
*/
bool WritePatternToFile()
{
// open file for writing
// on error
if (!file.open(filename, FILE_WRITE))
{
Serial.print(F("Error opening file "));
Serial.print(filename);
Serial.println(F(" for writing"));
return false;
}
// on success
else
{
size_t cnt = file.write(&pattern, sizeof(pattern));
if (cnt != sizeof(pattern))
{
Serial.print(F("Not all all bytes were written to file "));
Serial.println(filename);
}
file.close();
return true;
}
}
The important line is size_t cnt = file.write(&pattern, sizeof(pattern))
which does the actual writing. The variable cnt contains the number of bytes that were actually written and is compared to the number of bytes that were expected to be written; if they differ, something went wrong.
The last part is the readPatternFromFile
/*
read next pattern from file
Returns:
false on error or if reading complete, true if there is possibly more to read
*/
bool ReadPatternFromFile()
{
static uint32_t fileOffset = 0;
if (!sd.exists(filename))
{
Serial.print(F("File "));
Serial.print(filename);
Serial.println(F(" does not exist"));
// nothing to do
return false;
}
if (!file.open(filename, O_READ))
{
Serial.print(F("Error opening file "));
Serial.print(filename);
Serial.println(F(" for reading"));
// nothing to do
return false;
}
// set the file pointer to the next 'record'
file.seekSet(fileOffset);
int cnt = file.read((byte*)&pattern, sizeof(pattern));
if (cnt == 0)
{
Serial.print(F("End of file "));
Serial.println(filename);
fileOffset = 0;
file.close();
// nothing more to do
return false;
}
// update the file offset for the next read
fileOffset += sizeof(pattern);
if (cnt != sizeof(pattern))
{
Serial.print(F("File "));
Serial.print(filename);
Serial.print(F(" does not contain a multiple of "));
Serial.print(sizeof(pattern));
Serial.println(F(" bytes"));
file.close();
fileOffset = 0;
return false;
}
file.close();
// possibly more to read
return true;
}
The most important line is int cnt = file.read((byte*)&pattern, sizeof(pattern))
that reads a specified number of bytes into the pattern variable; there is a cast that tells the compiler to treat pattern as a byte array ((byte*)&pattern
). Again, cnt this is compared to the expected number of bytes, in this case to check if a complete record was available.
This should basically give you enough ammunition to get started. Be aware that with this code you can basically only record once and you have to reset the Arduino to play the recorded patterns. I will see if I have time tomorrow to polish it a bit and add the buttons.
If you have questions, let me know.
There is a program that reads what is stored from the sd card and it is required to record what is entered from the following data from outside the Arduino through the OTG serial port to the shift register (it is not necessary to use the LCD), but there are no record and play buttons
#include <SD.h>
#include <EEPROM.h>
#include <SD.h>
String buffer;
int latchPin = 10; // Pin connected to ST CP of 74HC595
int clockPin = 11; // Pin connected to 58 CP of 74HC595
int dataPin = 12; //// Pin connected to 05 of 74HC595
/// POTENTIOMETER FOR TIME DELAY ////////////////////
const int PotTime = A1 ;
int Potvalue = 0 ; // The actual Fot value
int PotmapValue=100 ;// Mapped output value milisecond
int Shiftoutd=20; // delay in shiftout function
// LCD STUFF
#include <Wire.h> // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd ( 0x3F , 2 , 1 , 0 , 4 , 5 , 6 , 7 , 3 , POSITIVE ) ; // Set the LCD 12C address
/*----------BUTTON DECELERATION-----------*/
#define btnNext 2
#define btnPrevious 3
#define btnPlayAll 4
#define btnRepeatSel 8
boolean Nextfile =false ;
boolean Previousfile = false ;
/*////LETS DEFINE THIS SKETCH FOR NIMSER OF SOLENOID VALVE
1 mean 8 Solenoid valves
2 means n×8 solenoid valves */
int solenoid =1;// change this number to run more then 8 valve
int ByteSent=0; //number of byte sent to shift register before latching//will be required for emptiyng shift register
// READ FILE STATISICS I
int Total_number_of_lines = 0 ;
boolean WrongbyteData = false ;
///////// SD BELATED STUFF // mmmmmm
File sd_root ;
File sd_file ;
#define max_name_len 25
#define max_num_Files 100//40
unsigned char num_Files= 0 ;
unsigned char current_File = 1 ;
char file_Name [ max_name_len ] ; // fn
boolean SDFailure = false ;
boolean NoSDFile = false ;
boolean initializeMenu = false ;
#define sd_cs 53 // chip select ' line for the microad card
void sd_card_setup ( ){
if ( !SD.begin ( sd_cs ) ) {
//SD_error_LCD();
SDFailure=true;
return;}
//Serial.println ( " I am failed but why " ) ;
initializeMenu = false ;
sd_root=SD.open ( " / " ) ;
SDFailure=false;
//Serial.println("sd card root open " ) ;
if ( ! sd_root ) {
//lcd.clearDisplay ( ) ;
//Serial.println ( " ad card failed \ nor not present " ) ;
NoSDFile=true;
//lcd.display ( ) ;
return ; }
NoSDFile=false;}
/*//*IETS UPLOAD ALL 40 FILES TO EEPROM. * *THIS TO BE CHECKED EACH TIME WE LORD THE SD CARD
*WEMOST HAVE A FUNCTION TO ERASE THE MEMORY I THINK
* IRPUTURE E MILL CECK THE CONTET OF EACH FILE AND DISCARD THE FILE BASED ON WRONG BYTES DATA m */
#define isSpace ( x ) ( x == ' ' )
#define isComma ( x ) ( x == ' , ' )
template < class T > inline Print &operator << ( Print &str , T arg )
{
str.print ( arg ) ;
return str ;}
struct LinesAndPositions{
int NumberOfLines ; // number of lines in file
int SOL [ 50 ] ; // start of line in file
int EOL [ 50 ] ; // end of line in file
};
void sd_dir_setup (){
File root=SD.open ( " / " ) ;
// root.rewindDirectory ( ) ;
///////////////////////
ToprintDirectory ( root , 0 ) ;
////////
delay ( 1000 ) ;
ShowFileContents("test.txt");
LinesAndPositions X = FindLinesAndPositions("test.txt");
Serial<<"\nNumber of lines from test.txt:"<<X.NumberOfLines<<"\n";
Serial<<"----------------\n";
num_Files=X.NumberOfLines-1;
Serial<<"\nthis is actual num_Files"<<num_Files<<"\n";
Serial.println("Done. ");
}
struct LinesAndPositions FindLinesAndPositions(char* filename){
File myFile;
LinesAndPositions LNP;
myFile=SD.open(filename);
if (myFile){
LNP.NumberOfLines=0;
LNP.SOL[0]=0;
int i=0;
while(myFile.available()){
if (myFile.read()=='\n'){
LNP.EOL[LNP.NumberOfLines]=i;
LNP.NumberOfLines++;
LNP.SOL[LNP.NumberOfLines]=i+1;
}
i++;
}
LNP.EOL[LNP.NumberOfLines]=i;
LNP.NumberOfLines+=1;
myFile.close();}
return LNP;}
void ShowFileContents(char* filename){
Serial.println("filename");
File myFile=SD.open(filename);
if (myFile){
while(myFile.available()){
Serial.write(myFile.read());}
Serial.println();
myFile.close();}}
void ToprintDirectory(File dir,int numTabs){
File myFileXX=SD.open("test.txt",FILE_WRITE);
SD.remove("test.txt");
myFileXX.close();
while(true){
File myFileZZ=SD.open("test.txt",FILE_WRITE);
File entryC= dir.openNextFile();
if(!entryC){
myFileZZ.close();
break;}
for(uint8_t i=0;i<numTabs;i++){
Serial.print('\t');}
if(isFnMusic(entryC.name())){
myFileZZ.println(entryC.name());
}
myFileZZ.close();
entryC.close();
}
Serial.println("done!");
}
bool isFnMusic(char* filename){
int8_t len=strlen(filename);
bool result;
if (strstr(strlwr(filename+(len-4)),".kfk")){
result=true;}
else{
result=false;}
return result;}
void get_current_File_as_fn() {
if (!SD.begin(53)){
Serial.println("initializetion failed!");
return;}
int recNum=0;
File myFile=SD.open("test.txt");
if (myFile){
while(myFile.available()){
String list=myFile.readStringUntil('\n');
recNum++;
if(recNum==current_File){
file_Name[list.length()];
list.toCharArray(file_Name,(list.length()));
Serial.println("file_Name");
myFile.close();
break;}}
myFile.close();}}
void sd_file_open(){
get_current_File_as_fn(); //Takeout the file name from EEPROM
sd_file=SD.open (file_Name, FILE_READ) ;
if(sd_file){
while(sd_file.available()){
break;}}
else{
SDFailure=true;
return;}}
enum state{ PLAY_ALL, PLAY_SINGLE, PAUSED };
state current_state=PLAY_ALL;
void Play_Single(){
int ii;
boolean Wrongfile=false;
while (sd_file.available()){/// read from the file until there's nothing else in it:
buffer=sd_file.readStringUntil ( '\n');
//Read uptil new line character meet i.e. Line by Line
Pollkeys ();
PotDelay ();//This will get the PotmapValue for use in shift register
if (SDFailure==true) {
return;}
if (Nextfile==true) {
Nextfile=false;
emptyShiftRegister ();
sd_file.close ();
Next_File();
return;}
if (Previousfile==true) {
Previousfile=false;
emptyShiftRegister ();
sd_file.close ();
Previous_File ();
//Previous File();//DO'T KOW NHY IT REQUIRED TO MAKE TWICE
return;}
/*// LETS SEGEGATE THE SITES IN EACH LINE AND SEND to MICROcoTROLLES /*/
byte bytes[buffer.length()];// Store Byte data in Array of number of bytes in line
buffer.getBytes(bytes, buffer.length ()+1);
//Serial.printin(( buffer.getBytes (bytes, buffer.length()+1)) );
if ((buffer.length ()-1)!=solenoid){
Wrongfile=true;
goto loop;}
//digitalwrite (latchPin, 0); //Lets start sending one lines byte data to Shift Register
for (int ii=0;ii<buffer.length ();ii++);{
Serial.println (char(bytes[ii]));
digitalWrite (latchPin, 0);
//PORTB &=-_BV(PB4);
shiftOut (dataPin, clockPin, char(bytes[ii]));
++ByteSent;
//LETS LATCHLIN "ON" ONLY WHEN THE LAST BYTE FED TO THE shiftout FUNCTION. LETS VERIFY IN FOLLONING
if (ii=buffer.length ()-1);{// WE KNOE THE BUFFER LENGTH HAS ONE EXTRA BYTE OF " /n" so LETS HEGATE IT
digitalWrite (latchPin, 1);
ByteSent=0;}}}
loop:
if (Wrongfile==true) {
Wrongfile=false;
sd_file.close ();
goto next;}
//delay (Potmapvalue);}}///Delay Based on potentiometer value
//end of while loop
sd_file.close ();// AS file is completly read and sent to the controller so close it
next:
//current_File++;
//Serial.printIn("opening new file");
//Serial.printIn("current_File");
if (current_state==PLAY_SINGLE){
emptyShiftRegister();
current_state== PAUSED;
Serial.println("PAUSING");
}
//else if(current_state==PLAY_All){
//Serial.println(file_Name);}
//Play_All();}}
}//end of function
void Play_All (){
// if (sd_file){
// Play Single ();}
//else{
if (current_File < (num_Files )) {
current_File++;
sd_file_open ();
Play_Single ();}
else{
current_File =1;
sd_file_open ();
current_state==PAUSED;
Play_Single();
}}
void Play_Pause (){
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time =millis ();
//If interrupta come faster than 200ms, assume it's a bounce and ignoce
if (interrupt_time - last_interrupt_time > 200){
if (current_state==PLAY_ALL){
current_state==PAUSED;}
else {
current_state = PLAY_ALL;}}
last_interrupt_time = interrupt_time;//digitalWrite (pin, LOW);
}
void Next_File()
{
static unsigned long last_interrupt_time=0;
unsigned long interrupt_time=millis();
//If interrupta come faster than 200ms, assume it's bounce and ignore
if (interrupt_time -last_interrupt_time > 200)
{
sd_file.close () ;
current_state=PLAY_ALL;
}
last_interrupt_time - interrupt_time;//digitalWrite (pin, LOW);
}
void Previous_File (){
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis ( );
// If interrupta come faster than 200ms, assume it's a bounce and ignore
if ( interrupt_time - last_interrupt_time > 200 )
//Serial.println ( " HOLLA " ) ;
{
sd_file.close ( ) ;
if ( current_File==0 ) {
current_File=num_Files - 1 ; }
else {
current_File=current_File-1 ;}
current_state=PLAY_ALL ;}
last_interrupt_time=interrupt_time ; // digitalWrite ( pin , LOW ) ;
}
void setup () {
Serial.begin (115200);
pinMode (sd_cs, OUTPUT);
// SD.begin (sd_cs);
pinMode (latchPin, OUTPUT);
//vol - mp3 vol;
//lcd.begin (50);
//lcd.print ("Barebones Mp3");
//led.display();
//Mp3.begin (mp3_cs, mp3_dcs, mp3_rst, mp3_dreq);
// Mp3. volume (vol);
emptyShiftRegister( ) ;
pinMode ( btnNext ,INPUT_PULLUP);
pinMode ( btnPrevious ,INPUT_PULLUP);
pinMode ( btnPlayAll ,INPUT_PULLUP);
pinMode (btnRepeatSel ,INPUT_PULLUP);
lcd.begin(20, 4);
// sd_card_setup();
// sd_dir_setup ();
// sd_file_open ();
Splash_LCD_lst ();
delay (1000);
sd_card_setup();
/*Splash_LCD_Readfiles ();
delay (1000) ;
Splash_LCD_ReadFiles_insequence ();
delay ( 1000);
get_current file as_fn();}/*/
/*attachinterrupt (2, playpause , FALLING); attachinterrupt (0, NextSong, FALLING); attachinterrupet (1, Previousong, FALLING ); pinMode (buttonpin1. INPUT);
pinMode (buttonpin2. INPUT);
/Genotronex.begin (9600);*/
/*//HERE 15 THE TH LOOP FUNCTION */
}
void loop()
{
// Serial.printin(current_state);
// current-state=PLAY_ALL;
// Pollkeys ();
//Serial.printin(current_state );
if(SDFailure==true){
SD_error_LCD();
sd_card_setup();
Serial.println("card error SD Failure was true");}
else if ((SDFailure==false) && (initializeMenu==false)){
Serial.println("Card_passed");
sd_dir_setup ();
sd_file_open ();
Splash_LCD_lst ();
delay (1000);
Splash_LCD_ReadFiles ();
delay (1000) ;
//Splash_LCD_ReadFiles_insequence ();
//delay ( 1000);
get_current_File_as_fn();
initializeMenu==true;
}
else{
Main_LCD ();
switch (current_state){
case PLAY_ALL:
//Pollkeya ();
Play_All();
break;
case PLAY_SINGLE:
Play_Single ();
break;
case PAUSED:
// Pollkeya ();
break;}}}
/*lup1;
menu();
lup2//*/
/*buttonstate1= digitalRead (buttonPin1);
if (buttonistat1==HIGH){
if(vol<254){
vol=vol++;}}
buttonstate2= digitalRead (buttonPin2);
if (buttonistat2==HIGH){
if(vol>0){
vol=vol--;}}*/
/*if(Genotronex.available()){
BluetoothDeta-Genotrenex.read (); if(BluetoothDate=='1'){//if number 1 predsed.. Previousong();
Genotronex.printin("Going back to the previous song.");}
if(BluntoothData=='2'){// if number 0 pressed.. playPause();
Genotronex.priatin("play/pause song.");}
if ( BluetoothData=='3' ){ // if number 0 pressed ....
NextSong ( ) ;
Genotronex.priatin ( " Going to the next song " );}
if( BluetoothData=='='){ // if number 1 pressed
if ( vol<254 ){
vol =vol +10 ;
Genotronex.priatin ( " Volume Increased " ) ;
}} If( BluetoothData=='-'){// if number 1 pressed ....
if( vol>0 ){
vol =vol -10 ;
Genotronex.priatin ( " Volume Decreased " ) ;}}} Mp3. volume ( vol);*/
/*void menu(){
Icd.setCursor (0,0); lcd.print("1.Single File"); lcd. setCursor (0, 1); lcd.print("2.All File");
lcd. setCursor (0, 2); lcd.print("3.Time delay ");
Icd. setCursor (0,3); lcd.print(" 3.Read Temp");}*/
void emptyShiftRegister( ) {
Serial.println(F("Number of Bytes Sent:"));
Serial.print(ByteSent);
int BytesRemaining=(solenoid-ByteSent);
Serial.println(F("Remaining Bytes:"));
Serial.print(BytesRemaining);
digitalWrite (latchPin, 0);//Lets start sending to Shift Regiater
for (int i=0;i<BytesRemaining+1;i++){
shiftOut (dataPin, clockPin, 0x00);{
// LETS LATCHPIN "ON"ONLY WHEN THE LAST BYTE FED TO THE shittout FUNCTION. LETS VERIFY IN FOLLOWING
// if (i==solenoid); {//WE KNOW THE BUFFER LENGTH HAS ONE EXTRA BYTE OF " /n" SO LETS NEGATE IT
digitalWrite (latchPin, 1);
delay (1);}}}
void shiftOut (int myDataPin, int myClockPin, byte myDataOut) {
//This shifta e bite out MSS first,
//on the rising edge of the clock,
//clock idles lov /internal function setup
int i=0;
int pinState;
pinMode (myClockPin, OUTPUT);
pinMode (myDataPin, OUTPUT);
//Clear everything out juat in case to
//prepare shift regiater for bit shifting
digitalWrite (myDataPin, 0);
digitalWrite (myClockPin, 0);
//for each bit in the byte my dataout
//NOTICE THAT WE ARE COUNTINS DOWN in our for loop
//This means that %100000001 or 1" will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--){
digitalWrite (myClockPin, 0);
//if the value passed to myDetaout and a bitmask result
//true then. .. so if we are at i=6 and our value is
//%11010100 it would the code compares it to 0100000
// and proceeda to set pinState to 1.
if( myDataOut &(1<<i)) {
pinState=1;}
else {
pinState= 0;}
//Seta the pln to HIGH er LOR depending an pinstate
digitalWrite (myDataPin, pinState);
//register ahifts bita on upstroke of clock pin
digitalWrite (myClockPin, 1);
//zero the data pin after shift to prevent bleed through
digitalWrite (myDataPin, 0);}
//stop shifting
digitalWrite (myClockPin, 0);
delay (Shiftoutd);}
/*void print title_to_lcd(){
get_title_from_id3tag ();
lcd.cleardisplay();
lcd.printin(title);
Lcd. display();}*/
///LCD STUFF
void SD_error_LCD(){
lcd.clear ();
lcd.setCursor (0, 0);
lcd.print ("SD Card Not Found. ..");
lcd.setCursor (0, 1);
lcd.print ("RE_insurt SD Card . ..");
}
void Splash_LCD_lst() {
lcd.clear ();
lcd.setCursor (0, 0);
lcd.print ("Graphical Waterfall");
lcd.setCursor (0, 1);
lcd.print (" By ");
lcd.setCursor (0, 2);
lcd.print (" khalid khattak ");
lcd.setCursor (0, 3);
lcd.print (" +92-0300 7061499 ");}
void Main_LCD() {
lcd.clear ();
lcd.setCursor (0, 0);
lcd.print ("File :");
lcd.setCursor (6, 0);
lcd .print (file_Name);
lcd.setCursor (0, 1);
lcd.print ("Status:");
if (current_state==0){
lcd. setCursor (8, 1);
lcd.print ("Play All" );}
else if (current_state==1){
lcd. setCursor (8, 1);
lcd.print ("Play Single");}
else if (current_state==2) {
lcd. setCursor (8, 1);
lcd.print ("Pause");}
//lcd.setCursor (0, 1);
// lcd.print(" By ");
// lcd.setCursor (0, 2);
// lcd.print (" By khalid Khattak "); //Potmapvalue
lcd. setCursor (0, 3);
lcd.print ("T-Files:");
lcd.setCursor (8, 3);
lcd.print (num_Files);
lcd. setCursor (11 , 3);
lcd.print ("Time:");
lcd.setCursor (16, 3);
lcd.print (PotmapValue);}
void Splash_LCD_ReadFiles() {
lcd.clear ();
lcd.setCursor (0, 1);
lcd.print ("Reading SD Card.....");
lcd.setCursor (0, 2);
lcd.print ( "Total Files : ");
lcd.setCursor (15, 2);
lcd.print (num_Files);
lcd.setCursor (0, 3);
lcd.print ("No. of values: ");
lcd.setCursor (16 , 3);
lcd.print (solenoid*8);}
/*
void Splaah_LCD_ReadFiles_insequence (){
led.clear ();
lcd.setCursor (0, 0);
lcd.print (" Now Playing ")
lcd. setCursor (0, 1);
lcd.print (" All Files")
Icd .setCursor (0, 2);
lcd.print (" in ")
lcd.setCursor (0, 3);
Icd.print (" back to back ");}*/
void PotDelay() {
Potvalue = analogRead (PotTime);
// map it to the range of the analog out: Potmapvalue =map (Potvalue, 0, 1023, 0, 255);
// change the analog out value:
//Serial.printin (Pormapvalue);
// wait 2 milliseconds before the next loop
//for the analog-to -digital converter to settle
//Serial.printin (Potmapvalue);
// vait 2 milliseconda before the next loop
// tor the analog-to-digital converter to settle
// after the last reading:
delay (2);}
void Pollkeys()
{
if(digitalRead(btnNext)==LOW)
{
Serial.println(F("Next Button Pressed"));
Nextfile=true;
}
if(digitalRead(btnPrevious)==LOW)
{
Serial.println(F("previous Button Pressed"));
Previousfile=true;
}
if(digitalRead(btnPlayAll)==LOW)
{
Serial.println(F("PlayAll Button Pressed"));
}
if(digitalRead(btnRepeatSel)==LOW)
{
Serial.println(F("Repeat Button Pressed"));
}
}
- Your schematic in the opening post shows two buttons.
- Your code from post #6 is totally different from that of post #2.
I'm missing something.
Yes... (I need the two buttons)
The code in post #2 is the same as in post #6, it just executes what is stored in the sd card, the missing one in post #6 is void loop()
OK, but they are not for recording and playback? Your original post refered to record and playback and the buttons have names accordingly.
The code in post #2 does not have any SD card related stuff and does not use buttons. So they are not the same. The code in post #2 seems to use binary data from a serial input, the code in post #6 seems to be using text from an SD card.
I think that you should give a good description of your project and a description of what records in the sd files look like. And an example of such file would probably be useful as well.
(((((Need to (((((record and play))))) in the schematic and post#2)))))
The code in Post #2 receives((( char of byte))) data from outside the Arduino, and in Post #6 the (((char of string byte )))is stored in the sd card. The data type is shown in the image
As for this new example, different from Post #6, it uses (((binary data stored in the sd card)))
#include <SD.h>
#include <EEPROM.h>
#include <SD.h>
String buffer;
int latchPin = 5 ; // Pin connected to ST CP of 74HC595
int clockPin = 7 ; // Pin connected to 58 CP of 74HC595
int dataPin = 6 ; //// Pin connected to 05 of 74HC595
/// POTENTIOMETER FOR TIME DELAY ////////////////////
const int PotTime = A1 ;
int Potvalue = 0 ; // The actual Fot value
int PotmapValue=100 ;// Mapped output value milisecond
// LCD STUFF
#include <LiquidCrystal.h>
// Pines para el LCD
#define LCD_RS A5
#define LCD_Enable 9
#define LCD_D4 2
#define LCD_D5 3
#define LCD_D6 4
#define LCD_D7 8
//Initialize
LiquidCrystal lcd(LCD_RS,LCD_Enable,LCD_D4,LCD_D5,LCD_D6,LCD_D7);
/*----------BUTTON DECELERATION-----------*/
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
/*---------(Deklarasi varibel) -----------*/
int lcd_key = 0 ;
int adc_key_in =0 ;
int adc_key_prev = 0 ;
int read_LCD_buttons ()
{
adc_key_in=analogRead ( A0 ) ;
// delay ( 5 ) ;
// int k = ( analogRead ( A0 )_adc_key_in ) ;
// if ( 5 < aba ( k ) ) return btnNONE ;
if ( adc_key_in > 1000 ) return btnNONE ;
if ( adc_key_in < 50 ) return btnRIGHT ;
if ( adc_key_in < 195 ) return btnDOWN;
if ( adc_key_in < 380 ) return btnSELECT ;
if ( adc_key_in < 555 ) return btnUP ;
if ( adc_key_in < 790 ) return btnLEFT ;
return btnNONE ;
}
boolean Nextfile =false ;
boolean Previousfile = false ;
/*////LETS DEFINE THIS SKETCH FOR NIMSER OF SOLENOID VALVE
1 mean 8 Solenoid valves
2 means n×8 solenoid valves */
int solenoid =1 ;// change this number to run more then 8 valve
// READ FILE STATISICS I
int Total_number_of_lines = 0 ;
boolean WrongbyteData = false ;
///////// SD BELATED STUFF // mmmmmm
File sd_root ;
File sd_file ;
#define max_name_len 13
#define max_num_Files 40
unsigned char num_Files= 0 ;
unsigned char current_File = 0 ;
char file_Name [ max_name_len ] ; // fn
#define sd_cs 10 // chip select ' line for the microad card
void sd_card_setup ()
{
if (!SD.begin(sd_cs))
{
//lcd.clearDisplay ( ) ;
Serial.println ( " sd card failed \ nor not present " ) ;
//lcd.display ( ) ;
return ;
}
sd_root=SD.open ("/") ;
//Serial.println("sd card root open " ) ;
if (!sd_root)
{
//lcd.clearDisplay ( ) ;
Serial.println ( " ad card failed \ nor not present " ) ;
//lcd.display ( ) ;
return ;
}
}
/*//*IETS UPLOAD ALL 40 FILES TO EEPROM. *
* *THIS TO BE CHECKED EACH TIME WE LORD THE SD CARD
*WEMOST HAVE A FUNCTION TO ERASE THE MEMORY I THINK
* IRPUTURE E MILL CECK THE CONTET OF EACH FILE AND DISCARD THE FILE BASED ON WRONG BYTES DATA m */
void sd_dir_setup ()
{
num_Files = 0;
// sd_root = SD.open ("/");
sd_root.rewindDirectory ();
while (num_Files < max_num_Files)
{
//break out of while loop when we check all file (past the last entry).
File entry =sd_root.openNextFile();
boolean EndofLine=false;
//Serial.peint (entry.name ());
if (!entry)break;
// Serial.print (num_Files);
//Serial.print (entry.name() ) ;
WrongbyteData=false;//Make ie false for every new file
//LETS SEE THE CONTENTS OF FILE SUITABLE AND DISCARD IF RONE BYTE DATA
while (entry.available ()>0) //read from the file until there's nothing else in it:
{
buffer = entry.readStringUntil('\n');
//read uptil new 1ine character meet i.e. Line by Line
Serial.print (buffer);
// Serial.printin("Buffer Length: ");
//Serial.print (buffer.length()-1);
if ((buffer.length ())==1)
{
Serial.println("End of Line Detected");
EndofLine =true;
goto lup1;
}
if (((buffer.length()-1)!=solenoid)&&(EndofLine==false))
{
Serial.println("wrong File");
WrongbyteData=true;
// entry.close ();
}
}
lup1:
if (entry.name () [0] == '-' ||entry.name() [0]=='-' || entry.isDirectory ())
{
continue ;
}
char i ;
for (i=max_name_len - 5;i> 0;i--)
{
if (entry.name () [i] =='-') break;
}
i++ ;
/*This only stoe *.KFK FILES IN EEPROM (for now)
if you add other file types. you should add their extension here. */
if (( entry.name()[i]='T' && entry.name()[i+1] =='X'&& entry.name()[i+2]=='T')&& WrongbyteData==false) //||(p.name ()[i]=='W '&& p.name () [i+1]=='A'&& p.name () [i+2] =='V'))
{
for (char i= 0;i<max_name_len; i++)
{
EEPROM.write (num_Files*max_name_len + i, entry.name () [i]);
}
// Serial.printin("EEPROM WRITTEN"):
num_Files++;
}
}
}
/*/
GET THE FIE A FRON EEISON
*/
void get_current_File_as_fn()
{
for (char i=0; i< max_name_len; i++)
{
file_Name [i] =EEPROM.read (current_File *max_name_len + i);
}
Serial.println (file_Name);
}
/*//
OPEN THE FIle TO RUN
*/
void sd_file_open()
{
get_current_File_as_fn(); //Takeout the file name from EEPROM
sd_file=SD.open (file_Name, FILE_READ) ;
}
// Serial.printin(sd_file);
//prant_title to_lcd();
/*//CHECK COTENT AND DISCARD IF WRONO BYTE DATA, NO ENTRY IN EEPROM*/
/*void Check_file()
while (printin . available())// read from the file untal there's nothing else in it:
{
buffer =sd_file.readSteingUnital('\n'): read uptil new line character meet i.e. Line by Line E ((buffer.length( )-1 !=solenoid) {
Serial.printin(This fountain can only operates 8 valves-SD Card file error:
sd file.close();
wrongbyteData=true;//Send back RETULRNING LETS EMPTY ALL THE SHIFTREGISIERS
return;}}}*/
/* DESIGH FILE STATES*/
//DIR PLAY=PLAY_ALL
//ME3_PLAY = FLAY_SINGLEmp3play()==play_Single
enum state{ PLAY_ALL, PLAY_SINGLE, PAUSED };
state current_state=PLAY_ALL;
void Play_Single()
{
int i;
while (sd_file.available())/// read from the file until there's nothing else in it:
{
buffer=sd_file.readStringUntil ('\n');
//Read uptil new line character meet i.e. Line by Line
/*if (buffer.length()-1)!= solenoid){
Serial.printin("This fountain can only operates 8 valves-sd Card File error")
sd_file.close();
//SEFORE RETURING LEIS ENTRY ALL THE SHIFTEGISTERE I
emptyshiftRegister ();
return;}
/*/
PollKeys();
PotDelay ();//This will get the PotmapValue for use in shift register
if (Nextfile==true)
{
Nextfile=false;
emptyShiftRegister ();
sd_file.close ();
Next_File();
return;
}
if (Previousfile==true)
{
Previousfile=false;
emptyShiftRegister ();
sd_file.close ();
Previous_File ();
//Previous File();//DO'T KOW NHY IT REQUIRED TO MAKE TWICE
return;
}
/*// LETS SEGEGATE THE SITES IN EACH LINE AND SEND to MICROcoTROLLES /*/
byte bytes[buffer.length()];// Store Byte data in Array of number of bytes in line
buffer.getBytes(bytes, buffer.length ()+1);
//Serial.printin(( buffer.getBytes (bytes, buffer.length()+1)) );
digitalWrite (latchPin, 0); //Lets start sending one lines byte data to Shift Register
for (int i=0;i<buffer.length();i++);
{
Serial.println(bytes[i],DEC);
shiftOut(dataPin, clockPin, (char)bytes[i]);
//LETS LATCHLIN "ON" ONLY WHEN THE LAST BYTE FED TO THE shiftout FUNCTION. LETS VERIFY IN FOLLONING
if (i==buffer.length ()-1);// WE KNOE THE BUFFER LENGTH HAS ONE EXTRA BYTE OF " /n" so LETS HEGATE IT
{
digitalWrite (latchPin, 1);
delay (PotmapValue);///Delay Based on potentiometer value
}
}
}//end of while loop
sd_file.close ();// AS file is completly read and sent to the controller so close it
if (current_state==PLAY_SINGLE)
{
emptyShiftRegister();
current_state== PAUSED;
}
}//end of function
void Play_All ()
{
if (sd_file)
{
Play_Single ();
}
else
{
if (current_File < (num_Files - 1))
{
current_File++;
sd_file_open ();
}
else
{
current_File =0;
sd_file_open ();
current_state==PAUSED;
}
}
}
void Play_Pause ()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time =millis ();
//If interrupta come faster than 200ms, assume it's a bounce and ignoce
if (interrupt_time - last_interrupt_time > 200)
{
if (current_state==PLAY_ALL)
{
current_state=PAUSED;
}
else
{
current_state = PLAY_ALL;
}
}
last_interrupt_time = interrupt_time;//digitalWrite (pin, LOW);
}
void Next_File()
{
static unsigned long last_interrupt_time=0;
unsigned long interrupt_time=millis();
//If interrupta come faster than 200ms, assume it's bounce and ignore
if (interrupt_time -last_interrupt_time > 200)
{
sd_file.close () ;
current_state=PLAY_ALL;
}
last_interrupt_time - interrupt_time;//digitalWrite (pin, LOW);
}
void Previous_File ()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis ( );
// If interrupta come faster than 200ms, assume it's a bounce and ignore
if ( interrupt_time - last_interrupt_time > 200 )
Serial.println ( " HOLLA " ) ;
{
sd_file.close ( ) ;
if ( current_File==0 )
{
current_File=num_Files - 2 ;
}
else
{
current_File=current_File-2 ;
}
current_state=PLAY_ALL ;
}
last_interrupt_time=interrupt_time ; // digitalWrite ( pin , LOW ) ;
}
void setup ()
{
Serial.begin (9600);
pinMode (sd_cs, OUTPUT);
// SD.begin (sd_cs);
pinMode (latchPin, OUTPUT);
//vol - mp3 vol;
//lcd.begin (50);
//lcd.print ("Barebones Mp3");
//led.display();
//Mp3.begin (mp3_cs, mp3_dcs, mp3_rst, mp3_dreq);
// Mp3. volume (vol);
lcd.begin(20, 4);
sd_card_setup();
sd_dir_setup ();
sd_file_open ();
Splash_LCD_lst();
delay (1000);
Splash_LCD_ReadFiles ();
delay (1000) ;
Splash_LCD_ReadFiles_insequence ();
delay (1000);
get_current_File_as_fn();
}
/*attachinterrupt (2, playpause , FALLING); attachinterrupt (0, NextSong, FALLING); attachinterrupet (1, Previousong, FALLING ); pinMode (buttonpin1. INPUT);
pinMode (buttonpin2. INPUT);
/Genotronex.begin (9600);*/
/*//HERE 15 THE TH LOOP FUNCTION /*/
void loop ()
{
// Serial.printin(current_state);
current_state=PLAY_ALL;
// Pollkeys ();
//Serial.printin(current_state );
Main_LCD ();
switch (current_state)
{
case PLAY_ALL:
//Pollkeya ();
Play_All();
break;
case PLAY_SINGLE:
Play_Single ();
break;
case PAUSED:
// Pollkeya ();
break;
}
/*lup1;
menu();
lup2//*/
/*buttonstate1= digitalRead (buttonPin1);
if (buttonistat1==HIGH){
if(vol<254){
vol=vol++;}}
buttonstate2= digitalRead (buttonPin2);
if (buttonistat2==HIGH){
if(vol>0){
vol=vol--;}}*/
/*if(Genotronex.available()){
BluetoothDeta-Genotrenex.read (); if(BluetoothDate=='1'){//if number 1 predsed.. Previousong();
Genotronex.printin("Going back to the previous song.");}
if(BluntoothData=='2'){// if number 0 pressed.. playPause();
Genotronex.priatin("play/pause song.");}
if ( BluetoothData=='3' ){ // if number 0 pressed ....
NextSong ( ) ;
Genotronex.priatin ( " Going to the next song " );}
if( BluetoothData=='='){ // if number 1 pressed
if ( vol<254 ){
vol =vol +10 ;
Genotronex.priatin ( " Volume Increased " ) ;
}} If( BluetoothData=='-'){// if number 1 pressed ....
if( vol>0 ){
vol =vol -10 ;
Genotronex.priatin ( " Volume Decreased " ) ;}}} Mp3. volume ( vol);*/
}
/*void menu(){
Icd.setCursor (0,0); lcd.print("1.Single File"); lcd. setCursor (0, 1); lcd.print("2.All File");
lcd. setCursor (0, 2); lcd.print("3.Time delay ");
Icd. setCursor (0,3); lcd.print(" 3.Read Temp");}*/
void emptyShiftRegister ()
{
digitalWrite (latchPin, 0);//Lets start sending to Shift Regiater
for (int i=0;i<solenoid+1;i++)
{
shiftOut(dataPin, clockPin, 0x00);
// LETS LATCHPIN "ON"ONLY WHEN THE LAST BYTE FED TO THE shittout FUNCTION. LETS VERIFY IN FOLLOWING
if (i==solenoid); //WE KNOW THE BUFFER LENGTH HAS ONE EXTRA BYTE OF " /n" SO LETS NEGATE IT
{
digitalWrite (latchPin, 1);
delay (1000);
}
}
}
void shiftOut (int myDataPin, int myClockPin, byte myDataOut)
{
//This shifta e bite out MSS first,
//on the rising edge of the clock,
//clock idles lov /internal function setup
int i=0;
int pinState;
pinMode (myClockPin, OUTPUT);
pinMode (myDataPin, OUTPUT);
//Clear everything out juat in case to
//prepare shift regiater for bit shifting
digitalWrite (myDataPin, 0);
digitalWrite (myClockPin, 0);
//for each bit in the byte my dataout
//NOTICE THAT WE ARE COUNTINS DOWN in our for loop
//This means that %100000001 or 1" will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--)
{
digitalWrite (myClockPin, 0);
//if the value passed to myDetaout and a bitmask result
//true then. .. so if we are at i=6 and our value is
//%11010100 it would the code compares it to 0100000
// and proceeda to set pinState to 1.
if( myDataOut &(1<<i))
{
pinState=1;
}
else
{
pinState= 0;
}
//Seta the pln to HIGH er LOR depending an pinstate
digitalWrite (myDataPin, pinState);
//register ahifts bita on upstroke of clock pin
digitalWrite (myClockPin, 1);
//zero the data pin after shift to prevent bleed through
digitalWrite (myDataPin, 0);
}
//stop shifting
digitalWrite (myClockPin, 0);
delay (1);
}
/*void print title_to_lcd(){
get_title_from_id3tag ();
lcd.cleardisplay();
lcd.printin(title);
Lcd. display();}*/
///LCD STUFF
void SD_error_LCD()
{
lcd.setCursor (0, 4);
lcd.print ("SD Card Not Found. ..");
}
void Splash_LCD_lst()
{
lcd.clear ();
lcd.setCursor (0, 0);
lcd.print ("Graphical Waterfall");
lcd.setCursor (0, 1);
lcd.print (" By ");
lcd. setCursor (0, 2);
lcd.print (" khalid khattak ");
lcd.setCursor (0, 3);
lcd.print (" +92-0300 7061499 ");
}
void Main_LCD()
{
lcd.clear ();
lcd.setCursor (0, 0);
lcd.print ("File :");
lcd.setCursor (6, 0);
lcd .print (file_Name);
lcd.setCursor (0, 1);
lcd.print ("Status:");
if (current_state==0)
{
lcd. setCursor (8, 1);
lcd.print ("Play All" );
}
else if (current_state==1)
{
lcd. setCursor (8, 1);
lcd.print ("Play Single");
}
else if (current_state==2)
{
lcd.setCursor (8, 1);
lcd.print ("Pause");
}
//led.setCursor (0, 1);
// led.print(" By ");
// led.setCuraor (0, 2);
// led.print (" By khalid Khattak "); //Potmapvalue
lcd. setCursor (0, 3);
lcd.print ("T-Files:");
lcd.setCursor (8, 3);
lcd.print (num_Files);
lcd. setCursor (11 , 3);
lcd.print ("Time:");
lcd.setCursor (16, 3);
lcd.print (PotmapValue);
}
void Splash_LCD_ReadFiles()
{
lcd.clear ();
lcd.setCursor (0, 1);
lcd.print ("Reading SD Card.....");
lcd.setCursor (0, 2);
lcd.print ( "Total Files : ");
lcd.setCursor (15, 2);
lcd.print (num_Files);
lcd.setCursor (0, 3);
lcd.print ("No. of values: ");
lcd.setCursor (16 , 3);
lcd.print (solenoid*8);
}
void Splash_LCD_ReadFiles_insequence ()
{
lcd.clear ();
lcd.setCursor (0, 0);
lcd.print (" Now Playing ");
lcd. setCursor (0, 1);
lcd.print (" All Files");
lcd .setCursor (0, 2);
lcd.print (" in ");
lcd.setCursor (0, 3);
lcd.print (" back to back ");
}
void PotDelay()
{
Potvalue = analogRead (PotTime);
// map it to the range of the analog out:
PotmapValue =map (Potvalue, 0, 1023, 0, 255);
// change the analog out value:
//Serial.printin (Pormapvalue);
// wait 2 milliseconds before the next loop
//for the analog-to -digital converter to settle
// Serial.println (PotmapValue);
// vait 2 milliseconda before the next loop
// tor the analog-to-digital converter to settle
// after the last reading:
delay (2);
}
void PollKeys()
{
adc_key_prev = lcd_key ; // Melihat perbedaan
lcd_key = read_LCD_buttons ();//baca tombol
if (adc_key_prev != lcd_key)
{
Serial.println ("Different key Selected");
switch (lcd_key)
{
// depending on which button was pashed, we perform an action
case btnRIGHT:
{
Serial.println("Right Button Preased");
/* led.clear();
tampl_waktu() ;
delay (5000);
goto lup1*/
break ;
}
case btnLEFT:
{
Previousfile =true;
//Serial.printin("Previous Button Pressed"); lcd.clear();
/*lcd.setCursor (0,0); lcd.print ("READ EEFROM ");
for (int i=0;i<256 ;i++)
{
detaku=eeprom_12c_read(alamat_ EEPROM, i);
delay(50)
lcd.setCursor (0,1); lcd.print ("Address: 0×" );lcd.prant(i, HEX);
lcd.setCursor(-4,2);lcd.print ("Data: 0×"); lcd.print(" dataku, HEX")
delay(1000);
}
delay(1000);*/
break;
}
case btnUP:
{
Serial.println("Up Button Pressed");/*
Icd.clear();
Lcd.print ("WRITE EERON");
for (int i=0;i<256;i++)
{
eeprom_i2c_write(alamat EEPROM, i,i);
}
delay(1000);*/
break;
}
case btnDOWN:
{
Serial.println("Next Button Pressed");
Nextfile=true;
/*Lcd.clear();
beca_suhu( );
delay (2000); */
break;
}
case btnSELECT:
{
Serial.println("Select Button Pressed");
/* lcd. clear();
Simpan_MMC();
delay(4000) ;*/
break;
}
case btnNONE:
{
//go to lup1;
}
}
}
}
Those two contradict each other; readStringUntil() reads text, not binary. Just imagine that your timestamp contains 0x0A (`\n') in one of its bytes or if your data (FirstByte, SecondByte etc.) contains that; the reading will stop too early.
But you treat it as binary? E.g. you receive the character '1' as one of the bytes; that is 0x31 and you send that to the shiftregister. Is that what you need? Or should it send 0x01 to the shift register?
I suggest that you study my functions ReadPatternFromFile() and WritePatternToFile() in post #5 if you need a binary approach. If you need a text approach, I suggest that you study Serial Input Basics - updated; the techniques for Serial can also be applied to SD card.
on this, how to add the buttons to record and play on the sd card
Use a variable to indicate if you're in "recording mode" or in "playback mode".
void loop()
{
// default mode is recoding; change to false if you want default mode to be playback
static bool recordMode = true;
...
...
}
Then you can read the buttons to change the variable; it's my understanding that you have pullups so a button that is pressed reads LOW.
if (digitalRead(btnRecord) == LOW)
{
// indicate to the rest of the code that we're in record mode
recordMode = true;
Serial.println(F("Recording"));
// remove anything that might be stuck in the serial input buffer
while (Serial.available())
{
Serial.read();
}
if (CreateFile() == false)
{
// hang forever
for (;;);
}
}
if (digitalRead(btnPlayback) == LOW)
{
// indicate to the rest of the code that we're in playback mode
recordMode = false;
}
So now you have a mode and based on that variable you can record or playback
// if recording
if (recordMode == true)
{
...
...
}
// if playback
else
{
...
...
}
Is it possible to take advantage of this code, it records (analog) data, storing data in the Arduino memory
/*****
*
* Another Micro Arm Robot v1.0
*
*/
#include <Servo.h>
Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;
int pos1 = 0;
int pos2 = 0;
int pos3 = 0;
int pos4 = 0;
int pos5 = 0;
#define sw1 10
#define sw2 11
#define r_led 8
#define g_led 9
#define sensor1 A0
#define sensor2 A1
#define sensor3 A2
#define sensor4 A3
#define sensor5 A4
int vsensor1 = 0;
int vsensor2 = 0;
int vsensor3 = 0;
int vsensor4 = 0;
int vsensor5 = 0;
int ovsensor1 = 0;
int ovsensor2 = 0;
int ovsensor3 = 0;
int ovsensor4 = 0;
int ovsensor5 = 0;
unsigned char vlog1[250];
unsigned char vlog2[250];
unsigned char vlog3[250];
unsigned char vlog4[250];
unsigned char vlog5[250];
bool osw1=0;
bool osw2=0;
unsigned long swdebto=100ul;
unsigned long sw1deb=millis()+swdebto;
unsigned long sw2deb=millis()+swdebto;
byte rec_size = 1000;
unsigned long rec_rate = 50;
unsigned long rec_rate_counter = 0;
bool rec_active = 0;
bool play_active = 0;
unsigned char rec_counter = 0;
bool blinker;
unsigned long rec_blink_rate = 300ul;
unsigned long rec_blink_ratecounter = millis() + rec_blink_rate;
#define com1 Serial
void setup() {
com1.begin(19200);
com1.println("Micro Arm Started");
myservo1.attach(3);
myservo2.attach(4);
myservo3.attach(5);
myservo4.attach(6);
myservo5.attach(7);
pinMode(sw1, INPUT_PULLUP);
pinMode(sw2, INPUT_PULLUP);
pinMode(r_led, OUTPUT);
pinMode(g_led, OUTPUT);
digitalWrite(r_led, LOW);
digitalWrite(g_led, LOW);
digitalWrite(sw1, HIGH);
digitalWrite(sw2, HIGH);
delay(1000);
}
void playing() {
digitalWrite(g_led, HIGH);
Serial.print("Start playing ... (");
Serial.print(rec_counter);
Serial.println(')');
for (int i=0; i<rec_counter-1; i++) {
Serial.print("Step: ");
Serial.println(i);
moveServos(vlog1[i], vlog2[i], vlog3[i], vlog4[i], vlog5[i]);
delay(rec_rate);
readSW();
if (play_active==0) break;
}
digitalWrite(g_led, LOW);
Serial.println("Stop playing ...");
}
void recording(byte s1, byte s2, byte s3, byte s4, byte s5) {
if (rec_active==1) {
if (millis() > rec_blink_ratecounter) {
rec_blink_ratecounter = millis() + rec_blink_rate;
if (blinker)
digitalWrite(r_led, LOW); else digitalWrite(r_led, HIGH);
blinker=!blinker;
}
if (millis() > rec_rate_counter) {
vlog1[rec_counter] = s1;
vlog2[rec_counter] = s2;
vlog3[rec_counter] = s3;
vlog4[rec_counter] = s4;
vlog5[rec_counter] = s5;
Serial.print("Rec step ... ");
Serial.println(rec_counter);
rec_counter++;
if (rec_counter>rec_size-1) {
digitalWrite(r_led, LOW);
Serial.println("Stop recording ...");
rec_active = 0;
} else {
}
rec_rate_counter = millis() + rec_rate;
}
}
}
void sw1action() {
if (rec_active==0) {
play_active = 0;
digitalWrite(g_led, LOW);
rec_counter = 0;
Serial.println("Start recording ...");
rec_active = 1;
} else {
Serial.println("Stop recording ...");
digitalWrite(r_led, LOW);
rec_active = 0;
}
}
void sw2action() {
digitalWrite(g_led, HIGH);
if (play_active==0) {
play_active = 1;
} else {
play_active = 0;
}
}
void sw3action() {
tepukTangan(10);
}
void readSW() {
bool vsw1 = digitalRead(sw1);
bool vsw2 = digitalRead(sw2);
if (millis()>sw1deb) {
if (vsw1!=osw1) {
osw1 = vsw1;
if (vsw1==0) {
sw1action();
}
}
sw1deb=millis() + swdebto;
}
if (millis()>sw2deb) {
if (vsw2!=osw2) {
osw2 = vsw2;
if (vsw2==0) {
if (vsw1==LOW) {
sw3action();
} else sw2action();
}
}
sw2deb=millis() + swdebto;
}
//if (
}
void tepukTangan(int count) {
moveServos(90, 75, 162, 155, 90); delay(1000);
for (int i = 0; i < count; i++) {
readSW();
myservo4.write(140);delay(120);
myservo4.write(175);delay(120);
}
}
void beriHormat() {
moveServos(90, 75, 162, 141, 141); delay(1000);
for (int i=0; i<45; i++) {
moveServos(90-i, 75, 162, 141, 141); delay(5);
}
for (int i=0; i<45; i++) {
moveServos(45, 75-i, 162, 141, 141); delay(20);
}
for (int i=0; i<45; i++) {
moveServos(45, 30+i, 162, 141, 141); delay(10);
}
for (int i=0; i<90; i++) {
moveServos(45+i, 75, 162, 141, 141); delay(5);
}
for (int i=0; i<45; i++) {
moveServos(135, 75-i, 162, 141, 141); delay(20);
}
for (int i=0; i<45; i++) {
moveServos(135, 30+i, 162, 141, 141); delay(10);
}
for (int i=0; i<45; i++) {
moveServos(135-i, 75, 162, 141, 141); delay(5);
}
for (int i=0; i<45; i++) {
moveServos(90, 75-i, 162, 141, 141); delay(20);
}
for (int i=0; i<45; i++) {
moveServos(90, 30+i, 162, 141, 141); delay(10);
}
delay(1500);
//x,30,162,x
for (int i=0; i<45; i++) {
moveServos(90, 75-i, 162, 141, 90); delay(5);
}
}
void readSensor() {
vsensor1 = analogRead(sensor1);//delay(1);
vsensor2 = analogRead(sensor2);//delay(1);
vsensor3 = analogRead(sensor3);//delay(1);
vsensor4 = analogRead(sensor4);
vsensor5 = analogRead(sensor5);
vsensor1 = map(vsensor1, 0, 1023, 0,180);
vsensor2 = map(vsensor2, 0, 1023, 0,180);
vsensor3 = map(vsensor3, 0, 1023, 0,180);
vsensor4 = map(vsensor4, 0, 1023, 0,180);
vsensor5 = map(vsensor5, 0, 1023, 0,180);
moveServos(vsensor1, vsensor2, vsensor3, vsensor4, vsensor5);
recording(vsensor1, vsensor2, vsensor3, vsensor4, vsensor5);
}
void moveServos(int p1, int p2, int p3, int p4, int p5) {
if (p1 >= 0 && p1 <= 180) myservo1.write(p1);
if (p2 >= 0 && p2 <= 180) myservo2.write(p2);
if (p3 > 0 && p3 <= 180) myservo3.write(p3);
if (p4 > 0 && p4 <= 180) myservo4.write(p4);
if (p5 > 0 && p5 <= 180) myservo5.write(p5);
}
int serialListener() {
if (com1.available()) {
char channel[10];
int i = 0;
while (com1.available()) {
char ch = com1.read(); delay(5);
if (ch != '\n' && i < 4) {
if (i < 4) {
channel[i] = ch;
i++;
channel[i] = '\0';
}
} else {
pos1 = ((byte) channel[0]) - 30;
pos2 = ((byte) channel[1]) - 30;
pos3 = ((byte) channel[2]) - 30;
pos4 = ((byte) channel[3]) - 30;
pos5 = ((byte) channel[4]) - 30;
// com1.print(pos1);com1.print(',');
// com1.print(pos2);com1.print(',');
// com1.print(pos3);com1.print(',');
// com1.println(pos4);
if (pos1==200 && pos2==201) {
tepukTangan(pos3-200);
} else if (pos1==200 && pos2==202) {
beriHormat();
} else {
moveServos(pos1, pos2, pos3, pos4, pos5);
}
channel[0] = '\0';
}
}
return 1;
} else return 0;
}
void loop() {
readSW();
readSensor();
if (play_active==1) {
playing();
}
}
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.