File.getFilename() in Arduino? - c++

UPDATE:There's no getfilename(), but there's name() function!
I'm trying to make a simple program to store all filenames in a String array and then show them in the LCD.
Code:
String* list(File root, int len) {
if (!root.isDirectory()) return NULL;
String files[50];
int i = 0;
while (true) {
File f = root.openNextFile();
if (i < 50) files[i] = f.getFilename();
f.close();
i++;
}
len = i;
root.close();
return files;
}
Code to display in LCD:
void displayToLCD(String* files, int len) {
lcd.clear();
lcd.home();
lcd.print("Files on SD:");
for (int i = 0; i < len; i++) {
lcd.setCursor(0, 1);
lcd.print(files[i]);
delay(1000);
}
lcd.clear();
lcd.home();
}
But the problem is that the class File doesn't have the 'getFilename()' function. Is there any way to get the filename?
Please help.
Best regards,
Mateiaru

Just remembered that that on arduino.cc at File section, at openNextFile example, they use File.name()! So there's no getFilename().
Mateiaru

I would recommend that you look at my MP3 FilePlayer.ino example. It accomplishes what you are attempting, but just to the serial port.
Additionally it won't run out of memory, as it does not store the file names into an array or memory. Rather displays them and lets the user select the number. This can also be readily adapted to an up/down arrow menu, for an LCD.
Note that I am using SdFat. It has more functions and attributes that are not made public in standard SD. along with the file.getFilename() .

Related

Overlap hundreds of histograms macro question

I have a directory trial which contains hundreds of histograms in it and a macro. Each is called in a way hists09876_blinded.root or hists12365_blinded.root. The order, however, is not like that. There are some missig histograms like hists10467_blinded.root hists10468_blinded.root hists10470_blinded.root. The ultimate goal is to get one histogram on a canvas which represents all of those combined together. The tricky thing is that each hists*****_blinded.root has around 15 1D histos in it, I need to pull out just one from each called sc*****.
I have 2 ideas, but I guess I should combine them together to get the final result.
First idea was to open histo by histo, but since there are some missed histos in the order, that does not work well.
void overlap()
{
TCanvas *time = new TCanvas("c1", "overlap", 0, 0, 800, 600);
const char* histoname = "sc";
const int NFiles = 256;
for (int fileNumber = 09675; fileNumber < NFiles; fileNumber++)
{
TFile* myFile = TFile::Open(Form("hists%i_blinded.root", fileNumber));
if (!myFile)
{
printf("Nope, no such file!\n");
return;
}
TH1* h1 = (TH1*)myFile->Get(histoname);
if (!h1)
{
printf("Nope, no such histogram!\n");
return;
}
h1->SetDirectory(gROOT);
h1->Draw("same");
myFile->Close();
}
}
After having read multiple posts on the pretty much the same question (1, 2, and this one) I have figured out what was wrong with my answer here: I did not know the file name may contain a zero if the number in its name is < 10000. Also, I failed to understand that the asterisks in the histogram name, which you refer to as sc*****, actually hide the same number as in the file name! I thought this was something completely different. So in that case I suggest you construct the file name and the histogram name you should be after in the same loop:
void overlap_v2()
{
TCanvas *time = new TCanvas("c1", "overlap", 0, 0, 800, 600);
const int firstNumber = 9675;
const int NFiles = 100000;
for (int fileNumber = firstNumber; fileNumber < firstNumber+NFiles; fileNumber++)
{
const char* filename = Form("trial/hists%05i_blinded.root", fileNumber);
TFile* myFile = TFile::Open(filename);
if (!myFile)
{
printf("Can not find a file named \"%s\"!\n", filename);
continue;
}
const char* histoname = Form("sc%05i", fileNumber);
TH1* h1 = (TH1*)myFile->Get(histoname);
if (!h1)
{
printf("Can not find a histogram named \"%s\" in the file named \"%s\"!\n", histoname, filename);
continue;
}
h1->SetDirectory(gROOT);
h1->Draw("same");
myFile->Close();
}
}
Since it is expected that some files are "missing", I suggest not to try to guess the names of the files that actually exist. Instead, use a function that lists all files in a given directory and from that list filter out those files that match the pattern of files you want to read. See for example these links for how to read the content of a directory in C++:
How can I get the list of files in a directory using C or C++?
http://www.martinbroadhurst.com/list-the-files-in-a-directory-in-c.html

How does AudioKit's AKNodeOutputPlot pull it's data?

I'm very new to the AudioKit framework and I have been trying to understand a bit more about the DSP side to it. Whilst rummaging around in the source code I realised that AKNodeOutputPlot does not pull data from the node the same way others would.
In the DSP code for the AKAmplitudeTracker an RMS value is calculated for each channel and the result is briefly written to the output buffer but at the end of the for loop the node is essentially bypassed by setting the output to the original input:
void process(AUAudioFrameCount frameCount, AUAudioFrameCount bufferOffset) override {
for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
int frameOffset = int(frameIndex + bufferOffset);
for (int channel = 0; channel < channels; ++channel) {
float *in = (float *)inBufferListPtr->mBuffers[channel].mData + frameOffset;
float temp = *in;
float *out = (float *)outBufferListPtr->mBuffers[channel].mData + frameOffset;
if (channel == 0) {
if (started) {
sp_rms_compute(sp, leftRMS, in, out);
leftAmplitude = *out;
} else {
leftAmplitude = 0;
}
} else {
if (started) {
sp_rms_compute(sp, rightRMS, in, out);
rightAmplitude = *out;
} else {
rightAmplitude = 0;
}
}
*out = temp;
}
}
}
This makes sense since outputting the RMS value to the device speakers would sound terrible but when this node is used as the input to the AKNodeOutputPlot object RMS values are plotted.
I assumed that the leftAmplitude and rightAmplitude variables were being referenced somewhere but even if they are zeroed out the plot works just fine. I'm interested in doing some work on the signal without effecting the output so I'd love it someone could help me figure how the AKPlot is grabbing this data.
Cheers
AKNodeOutputPlot works with something called a "tap":
https://github.com/AudioKit/AudioKit/blob/master/AudioKit/Common/User%20Interface/AKNodeOutputPlot.swift
There are also a few other taps that are not necessarily just for user interface purposes:
https://github.com/AudioKit/AudioKit/tree/master/AudioKit/Common/Taps
Taps allow you to inspect the data being pulled through another node without being inserted into the signal chain itself.

Serial COM Programming : Random Numbers

i need a little help with my coding.. see the coding below is used if we were to write a string and send through a com port.. what if we were to generate random strings and send it through a com port.. what do i actually have to change in the "this->serialPort1->WriteLine(message);" ? tried several codes from google.. none of them are working
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) {
//add sender name
String^ name = this->serialPort1->PortName;
// grab text and store in send buffer
String^ message = this->textBox2->Text;
// write to serial
if(this->serialPort1->IsOpen)
//this->_serialPort->WriteLine(String::Format("<{0}>: {1}",name,message));
this->serialPort1->WriteLine(message);
else
this->textBox2->Text="Port Not Opened";
}
//Sorry for the bad format. Must learn how to use it correctly.
void createRandom(std::string & randString, const int len)
{
static const std::string theCharacters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < len; ++i)
{
//generate a random number which not bigger that max size of the available characters, then add it to the string.
randString += theCharacters[rand() % (sizeof(theCharacters) - 1)];
}
}
createRandom(message);
this->serialPort1->WriteLine(message);

How do I convert my GPS NEMA sentences to a string using an Arduino?

I am attempting to parse information from a GPS module using an Arduino Uno. My thought was to convert the NEMA sentences to strings, then use a simple code to split the comma separated text into groups. Once that is accomplished I can then display certain portions of those groups to a screen.
Is this possible? I have included my very simple code below. Please keep in mind I am a beginner when it comes to code.
int rxPin = 0; // RX PIN
int txPin = 1; // TX TX
String text = Serial.read();
String message = text;
int commaPostion;
void setup() {
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
Serial.begin(4800);
Serial.println(message);
do{
commaPosition = message.indexof(',');
if(commaPosition != -1)
{
Serial.println(message.substring(0,commaPosition));
message = message.substring(commaPosition+1, message.length());
}
else
{ //here after last comma is found
if(message.length() > 0)
Serial.println(message);
}
while(commaPosition >=0);
{
}
void loop() {
}
In programming, laziness is a virtue. Why reinvent the wheel, right?
Check out the TinyGPS library designed to do exactly what you're trying to accomplish.

Error in Arduino programming

I am receiving the following error:
error: expected constructor, destructor, or type conversion before ‘(’ token
Here is the source code that I have written:
void setup() {
pinMode(1,OUTPUT);
[...]
pinMode(13,INPUT);
}
int i = 1;
bool pushed = digitalRead(13);
bool val = 0;
randomSeed(analogRead(0));
void loop() {
if (pushed == 1) {
for (i = 1; i < 9; i++) {
val = random(2);
digitalWrite(i,val);
}
}
}
The variables and the setup are OK; the error is located on the for line. Can anyone tell me how to fix this?
(edit : added the begining of the script, and sorry for the presentation (first question here)
(edit : looks like the error is not in the "i" definition. I'm using an Arduino UNO SMD Edition, if that helps (and the arduino alpha 0022 linux version of the IDE) )
EDIT: okay guys, solved now. It appears that my version of Arduino IDE was not completely downloaded, and that I put the randomSeed in the wrong place (it should be in the setup function.) (when i did put it in the setup function before updating, it shown an error message, saying /opt/arduino/lib/math.h was missing something (or something like that, i don't have the full message) ). Thanks for your help and i hope i'll be able to help you in arduino soon!
for (int i = 1; i < 9; i++)
is valid in C99/C11 but not valid in C89.
If you use a C89 compiler you have to define i outside the for loop clauses:
int i;
for (i = 1; i < 9; i++)
Also in C89, all declarations have to follow the left brace of a block, you cannot freely mix declarations and statements.
You appear to have a statement randomSeed(analogRead(0)); floating in between your setup() and loop() function definitions.
Move it and any other IO operations to the end of the setup() function so you read after setting up the pin directions:
int i = 1;
bool pushed;
bool val = 0;
void setup() {
pinMode(1,OUTPUT);
[...]
pinMode(13,INPUT);
pushed = digitalRead(13);
randomSeed(analogRead(0));
}
void loop() {
if (pushed == 1) {
for (i = 1; i < 9; i++) {
val = random(2);
digitalWrite(i,val);
}
}
}
That will reading the value of pin 13 into pushed only once ( e.g. you are holding a button when powering it on ); depending what you want it to do you may want to move the read to the start of loop() so writes random values whenever the button is pressed.
In C (previous to C99), it's not permissible to define a new variable in the first expression of a for loop. Try declaring your variable i at the top of the function instead.
#define pinMode1 1
#define pinMode2 13
bool pushed;
bool val = 0;
void setup() {
// Declare OUTPUT pin.
pinMode(pinMode1, OUTPUT);
// Declare INPUT pin.
pinMode(pinMode2, INPUT);
// Set digitalRead().
pushed = digitalRead(pinMode2);
// Initializes the pseudo-random number generator.
randomSeed(analogRead(0));
}
void loop() {
if (pushed == 1) {
for (int i = 1; i < 9; i++) {
val = random(2);
// Set i to HIGH or LOW.
digitalWrite(i, val);
}
}
}