B4R Question (NOT SOLVED no way...)SD and USBFAT library incompatibility.

tigrot

Well-Known Member
Licensed User
Longtime User
Hi Everybody!
Just 10 or more years since I used C++ last time. Now I have this issue. I have to use SD library(the one wrapped in B4R) and USB-host. The first to read/write SD and the second for USB memory stick.
This is my code:
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    Dim timer1 As Timer
    Dim y=2017,m=11,d=25,hh=13,mm=23,ss=00 As Int ' date and time fields with init time.
    Dim rtcres As Boolean ' result of native code calls (true=OK)
    Dim sd As SD
    Public buffer(200) As Byte
    Public raf As RandomAccessFile
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    sd.Initialize(10)
    If sd.Exists("/")=False Then
        Log("Nessuna scheda")
    End If
    For Each f As File In sd.ListFiles("/")
        Log(f.Name, TAB, Round(f.Size / 1024), "kb", TAB, f.IsDirectory)
        sd.OpenRead(f.name)
        Log("Lunghezza:")
        Log( sd.CurrentFile.Size)
        sd.Stream.ReadBytes(buffer, 0, buffer.Length)
        raf.CurrentPosition = 0
        'read the data from the buffer
        Log(buffer)
        sd.close
    Next
End Sub
#if C

#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>
#include <TimeLib.h>
#include <SPI.h>
#include <UsbFat.h>
#include <masstorage.h>

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}  

void setRTC(B4R::Object* bho)
{
  tmElements_t tm;
  int Hour, Min, Sec;
  int Month;
  int Day, Year;
  //Serial.print("Start:");
 
 // if (Month>12 || Month==0) return false;
  tm.Hour = b4r_main::_hh;
  tm.Minute = b4r_main::_mm;
  tm.Second = b4r_main::_ss;
  tm.Day = b4r_main::_d;
  tm.Month = b4r_main::_m;
/*
  Serial.print("Written Time = ");
  print2digits(tm.Hour);
  Serial.write(':');
  print2digits(tm.Minute);
  Serial.write(':');
  print2digits(tm.Second);
  Serial.print(", Date (D/M/Y) = ");
  Serial.print(tm.Day);
  Serial.write('/');
  Serial.print(tm.Month);
  Serial.write('/');
  Serial.print(b4r_main::_y);
  Serial.println();
*/
  tm.Year = CalendarYrToTm(b4r_main::_y);

  bool res=RTC.write(tm);
  b4r_main::_rtcres=res;
  return res;
}


void read(B4R::Object* unused) {
  tmElements_t tm;
  if (RTC.read(tm)) {
    /*
    Serial.print("Ok, Time = ");
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.write(':');
    print2digits(tm.Second);
    Serial.print(", Date (D/M/Y) = ");
    Serial.print(tm.Day);
    Serial.write('/');
    Serial.print(tm.Month);
    Serial.write('/');
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.println();
   */
    b4r_main::_hh=tm.Hour;
    b4r_main::_mm=tm.Minute;
    b4r_main::_ss=tm.Second;
    b4r_main::_d=tm.Day;
    b4r_main::_m=tm.Month;
    b4r_main::_y=tmYearToCalendar(tm.Year);
    b4r_main::_rtcres=true;
    return true;
  } else {
    if (RTC.chipPresent()) {
      Serial.println("The DS1307 is stopped.  Running SetTime");
     
      Serial.println();
      b4r_main::_rtcres=false;
      return false;
    } else {
      Serial.println("DS1307 read error!  Please check the circuitry.");
      Serial.println();
      b4r_main::_rtcres=false;
      return false;  
    }
    delay(9000);
  }
  delay(1000);
}


// USB host objects.
USB usb;
BulkOnly bulk(&usb);

// File system.
UsbFat key(&bulk);

// Test file.
File file;

//---------Inizializza USB
void setupx() {

  Serial.print(F("FreeRam "));
  Serial.println(FreeRam());
  Serial.println(F("Type any character to begin"));
  while (Serial.read() < 0) {}
 
  // Initialize the USB bus.
  if (!initUSB(&usb)) {
    Serial.println(F("initUSB failed"));
    return;  
  }
  // Init the USB key or USB hard drive.
  if (!key.begin()) {
    Serial.println(F("key.begin failed"));
    return;
  }
  Serial.print(F("\r\nVolume Size: "));
  // Avoid 32-bit overflow for large volumes.
  Serial.print((key.volumeBlockCount()/1000)*512/1000);
  Serial.println(F(" MB"));
 
  // Print a line to a test file.
  file.open("test file.txt", O_CREAT | O_RDWR);
  file.println("Hello USB");
  file.close();
 
  // List the files in the root directory.
  Serial.println();
  key.ls(LS_A | LS_DATE | LS_SIZE);
  Serial.println();
 
  Serial.println(F("Done"));
}

#end if
The two sketches compile well if it's done separatelly, when I put together I get this long list of errors, because FAT's structures are redefined in SD and USB libraries.

Of course I could redefine the constants and data types, but it's possible to void this kind of error? It's first time I happen!

Thank You

Mauro
 

Cableguy

Expert
Licensed User
Longtime User
Are you using a single device? Could a 2 device approach, using maybe I2C, be useful?
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
The issue is not in fisical device handling, but in fat handling. The creator has redefined FAT and FAT16 structures, so it's almost impossible to compile using a mix of SD and USB flash. I'm thinking to switch to Vinculum FTDI solution, using a two ports module. One of them will keep the local data(for a data logging) and one will have a removable USB flash, to extract data and elaborate it, keeping the logger running, while performing the task.
I have seen many solutions, but using dos compatible filesystem is a must.
Do you have some hint for me?
Thank you!
Mauro
 
Last edited:
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
DO you really need it to be "arduino"? reading you I would go with a Pi, even a zero, would allow you to use so many different approaches...
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
Of course: Orange Pi was my first chose. I have used Unix, Xenix and Linux from the beginning, but the logger must be powered from a weak power supply(a food metal detector, a project of mine). I have only 400ma left to me, before the detector will come unstable.
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
Got it! I have 5v at 400ma. I can drive a UNO + a 4x20 LCD + RS232 voltage shifter.
Tomorrow I'll order a Zero, which has SD and Host USB on board. And it costs less than the full bundle of arduino Shields!
web-it-out
The food factories are not willing to show the results of their tests. Better to keep secret! http://www.metaldetectorcoel.it/ that's my project, started in late '90.
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
by web-it-out I meant that you could export the results instead of logging in USB... that way, you could have a "sensor-network" logging into a central device
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
In normal case it is so, but I cannot use BT or WI-FI. They disturb coils. And make unstable an already unstable device!
Thank you guys(and ladies).
then be sure to NOT order the Zero-W versions as it comes with Bluetooth and Wifi built-in

You're welcome sir, just trying to help, but I mostly just get people even more confused...
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
then be sure to NOT order the Zero-W versions as it comes with Bluetooth and Wifi built-in
Hi Cableguy, is Rasberry safe in this environment?
I need to switch off power and cannot switch module before. Need to write SD, open/write/close file. It's not a large number of data. I have the feeling that the SD may corrupt in a few months.
Ciao
Mauro
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
You have the orange equivalents or banana's that have MMC so SD corruption shouldn't be a problem, also has sata connection
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…