Navigation

    Sony's Developer World forum

    • Register
    • Login
    • Search
    • Home
    • Forum guidelines
    1. Home
    2. KamilTomaszewski
    K
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Groups

    KamilTomaszewski

    @KamilTomaszewski

    DeveloperWorld

    31
    Posts
    7543
    Profile views
    1
    Followers
    0
    Following
    Joined Last Online

    KamilTomaszewski Follow
    DeveloperWorld

    Best posts made by KamilTomaszewski

    • RE: Need assistance for Ethernet interface

      Hi Daniel,

      I have a solution for you. First of all, use the Ethernet library from my fork (https://github.com/kamtom480/Ethernet). Secondly, you need to connect some pins on the Ethernet shield. Connect pins 11 (MOSI), 12(MISO), 13(SCK) located on the ICSP Header with pins 11, 12, 13 located on the Digital Header (11 -> 11, 12 -> 12, 13 -> 13). Now you should be able to use Ethernet with Spresense board. If something does not work or is unclear then let me know.

      Best regards,
      Kamil

      posted in Spresense
      K
      KamilTomaszewski
    • RE: How to use the clock in SPRESENSE

      @the_mutt CONFIG_USEC_PER_TICK is set to 10000, so the precision is 10 us. See https://github.com/sonydevworld/spresense-nuttx/blob/master/sched/Kconfig#L96

      posted in Spresense
      K
      KamilTomaszewski

    Latest posts made by KamilTomaszewski

    • RE: spresense with matlab?

      Hi @tornedoar

      Unfortunately, Spresense is not supported in Matlab. If you want to use Arduino on Spresense then use Arduino IDE. Here is a link on how to get started: https://developer.sony.com/develop/spresense/docs/arduino_set_up_en.html

      You can use the same libraries and code as on Arduino. However, there are some differences: https://developer.sony.com/develop/spresense/docs/arduino_developer_guide_en.html#_functional_differences

      I hope this will help you.

      Best Regards,
      Kamil Tomaszewski

      posted in Spresense
      K
      KamilTomaszewski
    • RE: GNSS - When is Time Valid? - Enhance NavData.posFixMode?

      @m-Lewis The easiest way to check that the date and time are valid is:

      /* Check update. */
      if (Gnss.waitUpdate(-1))
      {
        /* Get NaviData. */
        SpNavData NavData;
        Gnss.getNavData(&NavData);
      
        /* Check date and time. */
        if (NavData.time.year > 1980)
        {
          /* Date and time are valid */
      }
      

      Best Regards,
      Kamil Tomaszewski

      posted in Spresense
      K
      KamilTomaszewski
    • RE: GNSS and Record Audio at the same time?

      @m-Lewis The code that I sent you records in mp3 format for 10 seconds and then ends. That's why you don't get logs after that.

      I noticed that WAV recording and GNSS usage doesn't work on SDK 2.0 together. There is a bug. I'll try to investigate it.

      I have two solutions for now:

      1. You can use MP3 instead of WAV format. It works with SDK2.0
      2. If you want to use WAV format you can use SDK1.5.1

      Below is the code for the second solution:

      // GNSS and Audio at the same time example, while writing data to a logfile and output to Serial port
      // M. Lewis
      
      bool doAudio = true; // Record Audio
      bool doGnss = true;   // GNSS/GPS
      bool doLed = true;    // Blink LED
      bool doStream = true; // Stream sampled data lines to Serial output at Sample Rate
      bool doFile = true;   // Stream sampled data lines to logFile at Sample Rate
      
      #include <Arduino.h>
      #include <arch/board/board.h>
      #include <SDHCI.h>
      #include <File.h>
      #include <Storage.h>
      #include <elapsedMillis.h>
      #include <GNSS.h>
      #include <RTC.h> // For setting realtime clock
      #include <Audio.h>
      
      
      SDClass theSD; // This is the SD card class
      File logFile; // File object
      //char* logName = "/mnt/spif/logfile.log";
      char* logName = "logfile.log";
      String logString;
      
      elapsedMillis sinceSample;
      int sampleMillis = 1000/10; // 10 Hz
      
      ////////////// LED Control //////////////
      
      unsigned long blinkStartMS;
      #define BLINK_MS 500 // number of millisecs for on or off
      
      int blinkMillis = 1000/2;  // 2 Hz
      elapsedMillis sinceBlink;
      
      void led_setup() {
        Serial.println("led_setup()");
        pinMode(LED0, OUTPUT); // Init the on-board SPresense LEDs
        pinMode(LED1, OUTPUT);
        pinMode(LED2, OUTPUT);
        pinMode(LED3, OUTPUT);
        blinkStartMS = 0 ;
      }
      
      void led_loop() {
        static bool state = true;
        if (sinceBlink < blinkMillis) {
          return;
        }
        sinceBlink = sinceBlink - blinkMillis;
        state = ! state;
        digitalWrite(PIN_LED0, state==false ? LOW : HIGH);
      }
      
      void led_setAll(bool state)
      {
        digitalWrite(PIN_LED0, state==false ? LOW : HIGH);
        digitalWrite(PIN_LED1, state==false ? LOW : HIGH);
        digitalWrite(PIN_LED2, state==false ? LOW : HIGH);
        digitalWrite(PIN_LED3, state==false ? LOW : HIGH);
      }
      
      static void Led_isPosfix(bool state)
      {
          digitalWrite(PIN_LED1, state==false ? LOW : HIGH);
      }
      
      static void Led_isError(bool state)
      {
          digitalWrite(PIN_LED3, state==false ? LOW : HIGH);
      }
      
      
      ////////////// Log File Control //////////////
      
      void file_setup()
      {
        Serial.println("file_setup() start");
      
        //logFile = Storage.open(logName, FILE_WRITE); // Open the file. Note: only one file can be open at a time
        if (! theSD.begin()) {
          Serial.print("uSD card is not present!!");
          while(1){;}
        }
          
        logString = String("MSec");
        if (doGnss) {
          logString += ",";
          logString += gnss_get_columns();
        }
        
        logString += "\r\n";
        Serial.print(logString.c_str());
      
        logFile = theSD.open(logName, FILE_WRITE); // Open the file. Note: only one file can be open at a time
        if (!logFile) {
          Serial.print("Could not open logFile");
          return;
        }
      
        if (logFile.size() < 1) { // Empty or non-existant file. Add header line
          logFile.write(logString.c_str(), strlen(logString.c_str()));
          logFile.close(); /* Close the file */
          //logFile.flush();
        }
      }
      
      ////////////// GNSS File Control //////////////
      
      #define STRING_BUFFER_SIZE  128       /**< %Buffer size */
      #define RESTART_CYCLE       (60 * 5)  /**< positioning test term */
      
      static SpGnss Gnss;                   /**< SpGnss object */
      SpNavData NavData;
      uint32_t recordCount;
      String gnssLatestString;
      void gnss_update_latestString();
      
      const uint16_t FAULT_GPS_TIME = 0x2; // NO GPS Time and Date
      const uint16_t FAULT_GPS_FIX = 0x4; // NO GPS Location
      uint16_t gps_fault = 0;
      
      /**
       * @enum ParamSat
       * @brief Satellite system
       */
      enum ParamSat {
        eSatGps,            /**< GPS                     World wide coverage  */
        eSatGlonass,        /**< GLONASS                 World wide coverage  */
        eSatGpsSbas,        /**< GPS+SBAS                North America        */
        eSatGpsGlonass,     /**< GPS+Glonass             World wide coverage  */
        eSatGpsQz1c,        /**< GPS+QZSS_L1CA           East Asia & Oceania  */
        eSatGpsGlonassQz1c, /**< GPS+Glonass+QZSS_L1CA   East Asia & Oceania  */
        eSatGpsQz1cQz1S,    /**< GPS+QZSS_L1CA+QZSS_L1S  Japan                */
      };
      
      static enum ParamSat satType =  eSatGps; /* Set this parameter depending on your current region. */
      
      void gnss_setSatType()
      {
          /* Setup GNSS
           *  It is possible to setup up to two GNSS satellites systems.
           *  Depending on your location you can improve your accuracy by selecting different GNSS system than the GPS system.
           *  See: https://developer.sony.com/develop/spresense/developer-tools/get-started-using-nuttx/nuttx-developer-guide#_gnss
           *  for detailed information.
          */
          switch (satType)
          {
          case eSatGps:
            Gnss.select(GPS);
            break;
      
          case eSatGpsSbas:
            Gnss.select(GPS);
            Gnss.select(SBAS);
            break;
      
          case eSatGlonass:
            Gnss.select(GLONASS);
            break;
      
          case eSatGpsGlonass:
            Gnss.select(GPS);
            Gnss.select(GLONASS);
            break;
      
          case eSatGpsQz1c:
            Gnss.select(GPS);
            Gnss.select(QZ_L1CA);
            break;
      
          case eSatGpsQz1cQz1S:
            Gnss.select(GPS);
            Gnss.select(QZ_L1CA);
            Gnss.select(QZ_L1S);
            break;
      
          case eSatGpsGlonassQz1c:
          default:
            Gnss.select(GPS);
            Gnss.select(GLONASS);
            Gnss.select(QZ_L1CA);
            break;
          }
      }
      
      /**
       * @brief Activate GNSS device and start positioning.
       */
      void gnss_setup() {
        int error_flag = 0;
        recordCount = 0;
        
        puts("gnss_setup() Initializing GNSS...");
        RTC.begin(); // Initialize RTC at first
      
        gps_fault = FAULT_GPS_FIX | FAULT_GPS_TIME; // assume no GPS time or fix, show a fault
      
        sleep(3); // Wait HW initialization done
        led_setAll(true); //  Turn on all LEDs
      
        Gnss.setDebugMode(PrintInfo);
        if (Gnss.begin() != 0)
        {
          Serial.println("Gnss begin error!!");
          error_flag = 1;
        }
        else
        {
          gnss_setSatType(); // Select International Sat Systems to use
          if (Gnss.start(COLD_START) != 0) // Start positioning
          {
            Serial.println("Gnss COLD_START error!!");
            error_flag = 1;
          }
          else
          {
            Serial.println("Gnss setup OK");
          }
        }
      
        //Gnss.start1PPS(); /* Start 1PSS output to PIN_D02 */
      
        led_setAll(false); //  Turn off all LEDs
      
        if (error_flag == 1)
        {
          Led_isError(true); // Set error LED3
          exit(0);
        }
        puts("gnss_setup() done\n");
      }
      
      /**
       * @brief %Print satellite condition.
       */
      static void print_condition(SpNavData *pNavData)
      {
        char StringBuffer[STRING_BUFFER_SIZE];
        unsigned long cnt;
      
        snprintf(StringBuffer, STRING_BUFFER_SIZE, "numSatellites:%2d\n", pNavData->numSatellites); // Print satellite count
        Serial.print(StringBuffer);
      
        for (cnt = 0; cnt < pNavData->numSatellites; cnt++)
        {
          const char *pType = "---";
          SpSatelliteType sattype = pNavData->getSatelliteType(cnt);
          switch (sattype) // Get satellite 3 letter string
          {
            case GPS:        pType = "GPS";        break;
            case GLONASS:    pType = "GLN";        break;
            case QZ_L1CA:    pType = "QCA";        break;
            case SBAS:       pType = "SBA";        break;
            case QZ_L1S:     pType = "Q1S";        break;
            default:         pType = "UKN";        break;
          }
      
          unsigned long Id  = pNavData->getSatelliteId(cnt);
          unsigned long Elv = pNavData->getSatelliteElevation(cnt);
          unsigned long Azm = pNavData->getSatelliteAzimuth(cnt);
          float sigLevel = pNavData->getSatelliteSignalLevel(cnt);
      
          snprintf(StringBuffer, STRING_BUFFER_SIZE, "[%2d] Type:%s, Id:%2d, Elv:%2d, Azm:%3d, CN0:", cnt, pType, Id, Elv, Azm );
          Serial.print(StringBuffer);
          Serial.println(sigLevel, 6);
        }
      }
      
      /**
       * @brief %Print position information.
       */
      static void print_pos(SpNavData *pNavData)
      {
        static int LastPrintMin = 0;
        char StringBuffer[STRING_BUFFER_SIZE];
      
        /* print time */
        snprintf(StringBuffer, STRING_BUFFER_SIZE, "%04d/%02d/%02d ", pNavData->time.year, pNavData->time.month, pNavData->time.day);
        Serial.print(StringBuffer);
      
        snprintf(StringBuffer, STRING_BUFFER_SIZE, "%02d:%02d:%02d.%06d, ", pNavData->time.hour, pNavData->time.minute, pNavData->time.sec, pNavData->time.usec);
        Serial.print(StringBuffer);
      
        /* print satellites count */
        snprintf(StringBuffer, STRING_BUFFER_SIZE, "numSat:%2d, ", pNavData->numSatellites);
        Serial.print(StringBuffer);
      
        /* print position data */
        unsigned char fixMode = pNavData->posFixMode;
        switch (fixMode)
        {
          case 2:   Serial.print("2D"); break;
          case 3:   Serial.print("3D"); break;
          case 0:   // FixInvalid: //Serial.print("No-Fix, "); break;  // FixInvalid:
          default:  Serial.print("No"); break;
        }
        Serial.print("-Fix(");
        Serial.print(fixMode);
        Serial.print("), ");
        
        if (pNavData->posDataExist == 0)
        {
          Serial.print("No Position");
        }
        else
        {
          Serial.print("Lat=");
          Serial.print(pNavData->latitude, 6);
          Serial.print(", Lon=");
          Serial.print(pNavData->longitude, 6);
        }
      
        Serial.println("");
      
        if (NavData.time.minute != LastPrintMin) // Print satellite information every minute
        {
          print_condition(&NavData);
          LastPrintMin = NavData.time.minute;
        }
      }
      
      void gnss_restart()
      {
        int error_flag = 0;
      
        ledOff(PIN_LED0); // Turn off LED0
        Led_isPosfix(false); // Turn off posFix LED1
       
        if (Gnss.stop() != 0)
        {
          Serial.println("Gnss stop error!!");
          error_flag = 1;
        }
        else if (Gnss.end() != 0)
        {
          Serial.println("Gnss end error!!");
          error_flag = 1;
        }
        else
        {
          Serial.println("Gnss stop OK.");
        }
      
        if (Gnss.begin() != 0)
        {
          Serial.println("Gnss begin error!!");
          error_flag = 1;
        }
        else if (Gnss.start(HOT_START) != 0)
        {
          Serial.println("Gnss hot start error!!");
          error_flag = 1;
        }
        else
        {
          Serial.println("Gnss restart OK.");
        }
      
        if (error_flag == 1)
        {
          Led_isError(true); // Set error LED3
          exit(0);
        }
      }
      
      void gnss_update_latestString() {
      
        // Following code block was in loop()
        bool goodFix;
        int upd=Gnss.waitUpdate(0); //-1);
        if (upd) // Check update
        {
          if (upd) { recordCount++; } // New GNSS data has come in
          Gnss.getNavData(&NavData); // Get NaviData
          goodFix = NavData.posDataExist && (NavData.posFixMode != FixInvalid);
          Led_isPosfix( goodFix ); // Set posFix LED1 if there is a Fix
          print_pos(&NavData); // Print position information
        }
      
        if (!upd) {
          return;
        }
      
        //Serial.printf("secondsSinceTime()=%.3f\n", GPS.secondsSinceTime());
        gnssLatestString = "GPS,";
        if (NavData.time.hour < 10) { gnssLatestString += '0'; }
        gnssLatestString += NavData.time.hour; gnssLatestString += ':';
        if (NavData.time.minute < 10) { gnssLatestString += '0'; }
        gnssLatestString += NavData.time.minute; gnssLatestString += ':';
        if (NavData.time.sec < 10) { gnssLatestString += '0'; }
        gnssLatestString += NavData.time.sec;
      
        // handle millisecs - GPS.milliseconds can fail prior to a fix, then returns a random string
        uint16_t millisecs = NavData.time.usec / 1000;
        //Serial.printf("Millisec=%u\n", millisecs);
        if (millisecs > 1000) {millisecs = 0;}
        gnssLatestString += '.';
        if (millisecs < 10) {
          gnssLatestString += "00";
        } else if (millisecs > 9 && millisecs < 100) {
          gnssLatestString += "0";
        }
        gnssLatestString += millisecs;
        
        gnssLatestString += ",";
        gnssLatestString += NavData.time.year; gnssLatestString += '/';
        gnssLatestString += NavData.time.month;  gnssLatestString += '/';
        gnssLatestString += NavData.time.day;
      
        char fixBuf[300];
        char lat, lon;
        //lat = (!NavData.latitude) ? 'n' : NavData.latitude; // needed when never had fix since GPS.lat initialized to 0
        //lon = (!NavData.longitude) ? 'w' : NavData.longitude;
        lat = 'n';
        lon = 'w';
        
        sprintf(fixBuf, ",%.6f,%c,%.6f,%c,%.1f,%.1f,%d,%d,%lu",
          NavData.latitude, lat, NavData.longitude, lon, NavData.altitude, NavData.velocity, (int)NavData.numSatellites, NavData.posFixMode, recordCount);
        gnssLatestString += fixBuf;
      }
      
      char* gnss_get_columns() { // return the column headers
        static char buf[200] = "GPS,Time,Date,Lat_deg,N/S,Lon_deg,E/W,Alt_m,Knots,Track_deg,Sats,Fix,Rcvd";
        char* s = buf;
        return s;
      }
      
      char* gnss_get_latest() // return pointer to CSV IMU data string
      {
        gnss_update_latestString();
        gps_fault = 0;
        int status = (NavData.posDataExist && (NavData.posFixMode != FixInvalid));
        if (! NavData.posDataExist) {
          gps_fault |= FAULT_GPS_FIX;
        } else {
          //gnss_upd_rtc(); // SPresense version of RTC
        }
        return (char*)gnssLatestString.c_str();
      }
      
      bool gnss_waitUpdate(int milliSecs) { // milliSecs to wait, or -1 to not wait. Assumes setup() was already called
        bool upd = false;
        upd=Gnss.waitUpdate(milliSecs); // Check update
        return upd;
      }
      
      void gnss_loop() {} // Nothing here, GNSS is run at the much slower Sample rate. See gnss_get_latest() above
      
      ////////////// AUDIO RECORDING CONTROL //////////////
      extern SDClass theSD; // Declared in sp_main.cpp
      AudioClass *theAudio;
      File wavFile;
      int file_count = 0;
      bool ErrEnd = false;
      
      static const uint32_t recording_time = 10; // Recording Time (Seconds) per wav file
      static const uint32_t recording_sampling_rate = 48000; // Sample Rate (16000 or 48000)
      static const uint8_t  recording_channel_number = 1; // Number of Input Mic Channels (1, 2, or 4)
      static const uint8_t  recording_bit_length = 16; // Audio Sample Bit Length (16 or 24)
      static const int32_t recording_byte_per_second = recording_sampling_rate * recording_channel_number * recording_bit_length / 8; // Bytes per Second
      static const int32_t recording_size = recording_byte_per_second * recording_time; // Total WAV File Size
      
      static void audio_attention_cb(const ErrorAttentionParam *atprm) // Called when audio internal error occurs
      {
        switch (atprm->error_code) {
          case AS_ATTENTION_CODE_INFORMATION:
          case AS_ATTENTION_CODE_WARNING:
            ErrEnd = false;
            printf("Audio_Attention_CB() info/warn code=0x%x\n", atprm->error_code);
            break;
          case AS_ATTENTION_CODE_ERROR:
          case AS_ATTENTION_CODE_FATAL:
          default:
            ErrEnd = true;
            printf("Audio_Attention_CB() error/fatal code=0x%x\n", atprm->error_code);
        }
      }
      
      void audio_setup()
      { 
        puts("audio_setup() Initializing the Audio Library...");
        theAudio = AudioClass::getInstance();
        theAudio->begin(audio_attention_cb);
      
        // Select microphone input device
        theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC_A, 210); //210 = 21.0 dB Mic Gain
        theAudio->initRecorder(AS_CODECTYPE_WAV,"/mnt/spif/BIN",recording_sampling_rate,recording_bit_length,recording_channel_number);
        puts("Setting up the Recorder...");
      
        // Open file for data write on SD card
        //wavFile = theSD.open("Sound.wav", FILE_WRITE);
        wavFile = theSD.open(String(file_count)+".wav", FILE_WRITE);
      
        /* Verify file open */
        if (!wavFile)
          {
            printf("Error opening the WAV file...");
            exit(1);
          }
      
        puts("Writing the WAV File Header...");
        theAudio->writeWavHeader(wavFile);
      
        puts("audio_setup() done\n");
      }
      
      void audio_loop() 
      {
        err_t errStatus; // recording end condition
        if (theAudio->getRecordingSize() > recording_size)
          {
            theAudio->stopRecorder();
            sleep(0.1);
            errStatus = theAudio->readFrames(wavFile);
            theAudio->closeOutputFile(wavFile);
            wavFile.close();
            file_count++;
            goto restartRecording;
          }
      
          errStatus = theAudio->readFrames(wavFile);  /* Read frames to record in file */
      
        if (errStatus != AUDIOLIB_ECODE_OK)
          {
            printf("File Ended! =%d\n", errStatus);
            theAudio->stopRecorder();
            goto restartRecording;
          }
      
        if (ErrEnd)
          {
            printf("Error End\n");
            theAudio->stopRecorder();
            goto exitSketch;
          }
      
        if (file_count > 10)
          {
            goto exitSketch;
          }
        return;
      
        restartRecording:
          wavFile = theSD.open(String(file_count)+".wav", FILE_WRITE);
          puts("Writing the WAV File Header...\n");
          theAudio->writeWavHeader(wavFile);
          puts("Starting the Recorder...\n");
          theAudio->startRecorder();
          puts("Next Recording Started...\n");
          return;
      
        exitSketch:
          puts("Exiting Sketch!\n");
          exit(1);
      }
      
      ////////////// MAIN SETUP() and LOOP() //////////////
      
      void main_setup() {  // put your setup code here, to run once:
        Serial.begin(115200);
        //while (!Serial) { ; } // wait for serial port to connect. Needed for native USB port only
      
        printf("main_setup() initializing logFile %s\n", logName);
      
        if (doFile)   { file_setup(); }
        if (doAudio)  { audio_setup(); }
        if (doLed)    { led_setup(); }
        if (doGnss)   { gnss_setup(); }
      
        puts("Start Recording");
        theAudio->startRecorder();
      
        Serial.println("\nSetup Complete\n");
      }
      
      char* time_getstring() // return pointer to date/time string
      {
        static String datetime;
        datetime = String((int)millis(), (unsigned char)DEC);
        return (char*)datetime.c_str();
      }
      
      void sampleData() {
        if (sinceSample < sampleMillis) { // check if the Sample timer has passed its interval
          return;
        }
        sinceSample = sinceSample - sampleMillis;
      
        // Sampling time has been reached, Sample the Data
        char* dataStr;
        logString = time_getstring(); // get the time string for the beginning of each line in the file
      
        if (doGnss) {
          dataStr = gnss_get_latest();
          logString += String(",") + dataStr;
        }
        
        if (doStream) {
          Serial.println(logString);
        }
        
        if (doFile) { // whether to do the data log file
          logFile = theSD.open(logName, FILE_WRITE);
          logFile.write(logString.c_str(), strlen(logString.c_str()));
          logFile.write("\r\n", 2);
          logFile.flush();
          logFile.close();
        }
      }
      
      void main_loop()
      {
        if (doAudio)  { audio_loop(); }
        if (doGnss)   { gnss_loop(); }
        if (doLed)    { led_loop(); } // Blink SPresense On-board LED
      
        sampleData();
      }
      
      void setup() { main_setup(); }
      void loop() { main_loop(); }
      

      Let me know if it works.

      Best Regards,
      Kamil Tomaszewski

      posted in Spresense
      K
      KamilTomaszewski
    • RE: Auduino Compiling error : stdio.h

      @pnj Please comment line 25:

      // #include <stdio.h>
      

      in file: *\AppData\Local\Arduino15\packages\SPRESENSE\hardware\spresense<version>\cores\spresense\Print.h
      and add:

      #include <stdio.h>
      

      to file: *\AppData\Local\Arduino15\packages\SPRESENSE\hardware\spresense<version>\cores\spresense\main.cpp

      Let me know if it helped.

      posted in Spresense
      K
      KamilTomaszewski
    • RE: Unique ID for device detection.

      @m-Lewis

      Below is the code that shows how to get board unique ID using Arduino:

      #include <sys/boardctl.h>
      
      void setup() {
        uint8_t raw_id[CONFIG_BOARDCTL_UNIQUEID_SIZE];
        Serial.begin(115200);
      
        boardctl(BOARDIOC_UNIQUEID, (uintptr_t) raw_id);
        for (int i = 0; i < CONFIG_BOARDCTL_UNIQUEID_SIZE; i++) {
          Serial.print(raw_id[i], HEX);
        }
      }
      
      void loop() {
      }
      
      posted in Spresense
      K
      KamilTomaszewski
    • RE: GNSS and Record Audio at the same time?

      Hi @m-Lewis,

      Below I put the code in which Spresense records Audio and reads positions from GNSS:

      #include <SDHCI.h>
      #include <Audio.h>
      
      #define RECORD_FILE_NAME "Sound.mp3"
      
      SDClass theSD;
      AudioClass *theAudio;
      
      File myFile;
      
      bool ErrEnd = false;
      
      /* include the GNSS library */
      #include <GNSS.h>
      
      #define STRING_BUFFER_SIZE  128       /**< %Buffer size */
      
      #define RESTART_CYCLE       (60 * 5)  /**< positioning test term */
      
      static SpGnss Gnss;                   /**< SpGnss object */
      
      /**
       * @enum ParamSat
       * @brief Satellite system
       */
      enum ParamSat {
        eSatGps,            /**< GPS                     World wide coverage  */
        eSatGlonass,        /**< GLONASS                 World wide coverage  */
        eSatGpsSbas,        /**< GPS+SBAS                North America        */
        eSatGpsGlonass,     /**< GPS+Glonass             World wide coverage  */
        eSatGpsBeidou,      /**< GPS+BeiDou              World wide coverage  */
        eSatGpsGalileo,     /**< GPS+Galileo             World wide coverage  */
        eSatGpsQz1c,        /**< GPS+QZSS_L1CA           East Asia & Oceania  */
        eSatGpsGlonassQz1c, /**< GPS+Glonass+QZSS_L1CA   East Asia & Oceania  */
        eSatGpsBeidouQz1c,  /**< GPS+BeiDou+QZSS_L1CA    East Asia & Oceania  */
        eSatGpsGalileoQz1c, /**< GPS+Galileo+QZSS_L1CA   East Asia & Oceania  */
        eSatGpsQz1cQz1S,    /**< GPS+QZSS_L1CA+QZSS_L1S  Japan                */
      };
      
      /* Set this parameter depending on your current region. */
      static enum ParamSat satType =  eSatGps;
      
      /**
       * @brief Turn on / off the LED0 for CPU active notification.
       */
      static void Led_isActive(void)
      {
        static int state = 1;
        if (state == 1)
        {
          ledOn(PIN_LED0);
          state = 0;
        }
        else
        {
          ledOff(PIN_LED0);
          state = 1;
        }
      }
      
      /**
       * @brief Turn on / off the LED1 for positioning state notification.
       *
       * @param [in] state Positioning state
       */
      static void Led_isPosfix(bool state)
      {
        if (state)
        {
          ledOn(PIN_LED1);
        }
        else
        {
          ledOff(PIN_LED1);
        }
      }
      
      /**
       * @brief Turn on / off the LED3 for error notification.
       *
       * @param [in] state Error state
       */
      static void Led_isError(bool state)
      {
        if (state)
        {
          ledOn(PIN_LED3);
        }
        else
        {
          ledOff(PIN_LED3);
        }
      }
      
      /**
       * @brief %Print position information.
       */
      static void print_pos(SpNavData *pNavData)
      {
        char StringBuffer[STRING_BUFFER_SIZE];
      
        /* print time */
        snprintf(StringBuffer, STRING_BUFFER_SIZE, "%04d/%02d/%02d ", pNavData->time.year, pNavData->time.month, pNavData->time.day);
        Serial.print(StringBuffer);
      
        snprintf(StringBuffer, STRING_BUFFER_SIZE, "%02d:%02d:%02d.%06d, ", pNavData->time.hour, pNavData->time.minute, pNavData->time.sec, pNavData->time.usec);
        Serial.print(StringBuffer);
      
        /* print satellites count */
        snprintf(StringBuffer, STRING_BUFFER_SIZE, "numSat:%2d, ", pNavData->numSatellites);
        Serial.print(StringBuffer);
      
        /* print position data */
        if (pNavData->posFixMode == FixInvalid)
        {
          Serial.print("No-Fix, ");
        }
        else
        {
          Serial.print("Fix, ");
        }
        if (pNavData->posDataExist == 0)
        {
          Serial.print("No Position");
        }
        else
        {
          Serial.print("Lat=");
          Serial.print(pNavData->latitude, 6);
          Serial.print(", Lon=");
          Serial.print(pNavData->longitude, 6);
        }
      
        Serial.println("");
      }
      
      /**
       * @brief %Print satellite condition.
       */
      static void print_condition(SpNavData *pNavData)
      {
        char StringBuffer[STRING_BUFFER_SIZE];
        unsigned long cnt;
      
        /* Print satellite count. */
        snprintf(StringBuffer, STRING_BUFFER_SIZE, "numSatellites:%2d\n", pNavData->numSatellites);
        Serial.print(StringBuffer);
      
        for (cnt = 0; cnt < pNavData->numSatellites; cnt++)
        {
          const char *pType = "---";
          SpSatelliteType sattype = pNavData->getSatelliteType(cnt);
      
          /* Get satellite type. */
          /* Keep it to three letters. */
          switch (sattype)
          {
            case GPS:
              pType = "GPS";
              break;
      
            case GLONASS:
              pType = "GLN";
              break;
      
            case QZ_L1CA:
              pType = "QCA";
              break;
      
            case SBAS:
              pType = "SBA";
              break;
      
            case QZ_L1S:
              pType = "Q1S";
              break;
      
            case BEIDOU:
              pType = "BDS";
              break;
      
            case GALILEO:
              pType = "GAL";
              break;
      
            default:
              pType = "UKN";
              break;
          }
      
          /* Get print conditions. */
          unsigned long Id  = pNavData->getSatelliteId(cnt);
          unsigned long Elv = pNavData->getSatelliteElevation(cnt);
          unsigned long Azm = pNavData->getSatelliteAzimuth(cnt);
          float sigLevel = pNavData->getSatelliteSignalLevel(cnt);
      
          /* Print satellite condition. */
          snprintf(StringBuffer, STRING_BUFFER_SIZE, "[%2d] Type:%s, Id:%2d, Elv:%2d, Azm:%3d, CN0:", cnt, pType, Id, Elv, Azm );
          Serial.print(StringBuffer);
          Serial.println(sigLevel, 6);
        }
      }
      
      /**
       * @brief Audio attention callback
       *
       * When audio internal error occurc, this function will be called back.
       */
      
      static void audio_attention_cb(const ErrorAttentionParam *atprm)
      {
        puts("Attention!");
        
        if (atprm->error_code >= AS_ATTENTION_CODE_WARNING)
          {
            ErrEnd = true;
         }
      }
      
      /**
       * @brief Setup recording of mp3 stream to file
       *
       * Select input device as microphone <br>
       * Initialize filetype to stereo mp3 with 48 Kb/s sampling rate <br>
       * Open RECORD_FILE_NAME file in write mode
       */
      
      /* Recording time[second] */
      
      static const int32_t recoding_time = 10;
      
      /* Recording bit rate
       * Set in bps.
       * Note: 96kbps fixed
       */
      
      static const int32_t recoding_bitrate = 96000;
      
      /* Bytes per second */
      
      static const int32_t recoding_byte_per_second = (recoding_bitrate / 8);
      
      /* Total recording size */
      
      static const int32_t recoding_size = recoding_byte_per_second * recoding_time;
      
      /**
       * @brief Activate GNSS device and start positioning.
       */
      void gnss_setup() {
        /* put your setup code here, to run once: */
      
        int error_flag = 0;
      
        /* Set serial baudrate. */
        Serial.begin(115200);
      
        /* Wait HW initialization done. */
        sleep(3);
      
        /* Turn on all LED:Setup start. */
        ledOn(PIN_LED0);
        ledOn(PIN_LED1);
        ledOn(PIN_LED2);
        ledOn(PIN_LED3);
      
        /* Set Debug mode to Info */
        Gnss.setDebugMode(PrintInfo);
      
        int result;
      
        /* Activate GNSS device */
        result = Gnss.begin();
      
        if (result != 0)
        {
          Serial.println("Gnss begin error!!");
          error_flag = 1;
        }
        else
        {
          /* Setup GNSS
           *  It is possible to setup up to two GNSS satellites systems.
           *  Depending on your location you can improve your accuracy by selecting different GNSS system than the GPS system.
           *  See: https://developer.sony.com/develop/spresense/developer-tools/get-started-using-nuttx/nuttx-developer-guide#_gnss
           *  for detailed information.
          */
          switch (satType)
          {
          case eSatGps:
            Gnss.select(GPS);
            break;
      
          case eSatGpsSbas:
            Gnss.select(GPS);
            Gnss.select(SBAS);
            break;
      
          case eSatGlonass:
            Gnss.select(GLONASS);
            break;
      
          case eSatGpsGlonass:
            Gnss.select(GPS);
            Gnss.select(GLONASS);
            break;
      
          case eSatGpsBeidou:
            Gnss.select(GPS);
            Gnss.select(BEIDOU);
            break;
      
          case eSatGpsGalileo:
            Gnss.select(GPS);
            Gnss.select(GALILEO);
            break;
      
          case eSatGpsQz1c:
            Gnss.select(GPS);
            Gnss.select(QZ_L1CA);
            break;
      
          case eSatGpsQz1cQz1S:
            Gnss.select(GPS);
            Gnss.select(QZ_L1CA);
            Gnss.select(QZ_L1S);
            break;
      
          case eSatGpsBeidouQz1c:
            Gnss.select(GPS);
            Gnss.select(BEIDOU);
            Gnss.select(QZ_L1CA);
            break;
      
          case eSatGpsGalileoQz1c:
            Gnss.select(GPS);
            Gnss.select(GALILEO);
            Gnss.select(QZ_L1CA);
            break;
      
          case eSatGpsGlonassQz1c:
          default:
            Gnss.select(GPS);
            Gnss.select(GLONASS);
            Gnss.select(QZ_L1CA);
            break;
          }
      
          /* Start positioning */
          result = Gnss.start(COLD_START);
          if (result != 0)
          {
            Serial.println("Gnss start error!!");
            error_flag = 1;
          }
          else
          {
            Serial.println("Gnss setup OK");
          }
        }
      
        /* Start 1PSS output to PIN_D02 */
        //Gnss.start1PPS();
      
        /* Turn off all LED:Setup done. */
        ledOff(PIN_LED0);
        ledOff(PIN_LED1);
        ledOff(PIN_LED2);
        ledOff(PIN_LED3);
      
        /* Set error LED. */
        if (error_flag == 1)
        {
          Led_isError(true);
          exit(0);
        }
      }
      
      void recorder_setup()
      {
        theAudio = AudioClass::getInstance();
      
        theAudio->begin(audio_attention_cb);
      
        puts("initialization Audio Library");
      
        /* Select input device as microphone */
        theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC);
      
        /*
         * Initialize filetype to stereo mp3 with 48 Kb/s sampling rate
         * Search for MP3 codec in "/mnt/sd0/BIN" directory
         */
        theAudio->initRecorder(AS_CODECTYPE_MP3, "/mnt/sd0/BIN", AS_SAMPLINGRATE_48000, AS_CHANNEL_STEREO);
        puts("Init Recorder!");
      
        /* Open file for data write on SD card */
      
        theSD.begin();
      
        if (theSD.exists(RECORD_FILE_NAME))
          {
            printf("Remove existing file [%s].\n", RECORD_FILE_NAME);
            theSD.remove(RECORD_FILE_NAME);
          }
      
        myFile = theSD.open(RECORD_FILE_NAME, FILE_WRITE);
        /* Verify file open */
        if (!myFile)
          {
            printf("File open error\n");
            exit(1);
          }
      
        printf("Open! [%s]\n", RECORD_FILE_NAME);
      
        theAudio->startRecorder();
        puts("Recording Start!");
      }
      
      void setup() {
        gnss_setup();
        recorder_setup();
      }
      
      /**
       * @brief Record given frame number
       */
      void loop() 
      {
          static int LastPrintMin = 0;
      
        /* Blink LED. */
        Led_isActive();
      
        /* Check update. */
        if (Gnss.waitUpdate(0))
        {
          /* Get NaviData. */
          SpNavData NavData;
          Gnss.getNavData(&NavData);
      
          /* Set posfix LED. */
          bool LedSet = (NavData.posDataExist && (NavData.posFixMode != FixInvalid));
          Led_isPosfix(LedSet);
      
          /* Print satellite information every minute. */
          if (NavData.time.minute != LastPrintMin)
          {
            print_condition(&NavData);
            LastPrintMin = NavData.time.minute;
          }
      
          /* Print position information. */
          print_pos(&NavData);
        }
      
        err_t err;
        /* recording end condition */
        if (theAudio->getRecordingSize() > recoding_size)
          {
            theAudio->stopRecorder();
            sleep(1);
            err = theAudio->readFrames(myFile);
      
            goto exitRecording;
          }
      
        /* Read frames to record in file */
        err = theAudio->readFrames(myFile);
      
        if (err != AUDIOLIB_ECODE_OK)
          {
            printf("File End! =%d\n",err);
            theAudio->stopRecorder();
            goto exitRecording;
          }
      
        if (ErrEnd)
          {
            printf("Error End\n");
            theAudio->stopRecorder();
            goto exitRecording;
          }
      
        /* This sleep is adjusted by the time to write the audio stream file.
           Please adjust in according with the processing contents
           being processed at the same time by Application.
        */
      //  usleep(10000);
      
        return;
      
      exitRecording:
      
        theAudio->closeOutputFile(myFile);
        myFile.close();
        
        theAudio->setReadyMode();
        theAudio->end();
      
        Gnss.stop();
        Gnss.end();
        
        puts("End Recording");
        exit(1);
      }
      

      Please let me know what was wrong with your application or share the code.

      Best Regards,
      Kamil Tomaszewski

      posted in Spresense
      K
      KamilTomaszewski
    • RE: How to set player_main as the SDK Application entry point?

      Hello @QiangLi

      This code was created based on the code from the Spresense Arduino Library (https://github.com/sonydevworld/spresense-arduino-compatible/blob/3ac9fd04398832052c9ef45d9738979877708384/Arduino15/packages/SPRESENSE/hardware/spresense/1.0.0/libraries/SDHCI/src/SDHCI.cpp#L66-L75).

      This is not in the documentation. If you use your function as an entry point, you must wait for the SD card mount if you want to use it.

      Here you can find information about Spresense board initialization process: https://developer.sony.com/develop/spresense/docs/sdk_developer_guide_en.html#_board_initialization_process

      BR,
      Kamil Tomaszewski

      posted in Spresense
      K
      KamilTomaszewski
    • RE: How to set player_main as the SDK Application entry point?

      Hi @QiangLi

      If you want to use some other function as an entry point, you must initialize the Spresense board in it.

      To do this, add it to the beginning of your main function (audio_player_main):

      boardctl(BOARDIOC_INIT, 0);
      

      The second thing you need to do is wait for the SD card to initialize.

      You can do this using this loop:

        /* In case that SD card isn't inserted, it times out at max 2 sec */
        for (retry = 0; retry < 20; retry++)
          {
            if (stat("/mnt/sd0/", &buf) == 0)
              {
                break;
              }
            /* 100 ms */
            usleep(100 * 1000);
          }
      
        if (retry >= 20)
          {
            printf("Error: SD card isn't inserted.\n");
            return 1;
          } 
      

      When you add these two things to the beginning of your main function (audio_player_main), everything should work now.

      BR,
      Kamil Tomaszewski

      posted in Spresense
      K
      KamilTomaszewski
    • RE: Questions about spresense-aruino-compatible

      Hello @ahoudeau

      The source code that was used by the prepare_arduino.sh script is version 1.4.2. You can check the git log and see the tag.

      Version 1.0.0 here does not apply to the Spresense Arduino Library version but only to the version of your custom Arduino15.

      You can change this to 1.4.2. Change all occurrences of 1.0.0 to 1.4.2 in the Arduino15 folder.

      It will not change anything in the source code. Everything will be the same. Only the Arduino IDE will see that this is a different package.

      You shouldn't have any problems. Maybe try:

      1. In the Arduino IDE go to Tools-> Board-> Board Manager... and remove Spresense.

      2. Go to %userprofile%\AppData\Local\Arduino15 and remove packages and package_spresense_index.json and other files that have spresense in their name.

      3. Copy packages and package_spresense_index.json from spresense-arduino-compatible/Arduino15 to %userprofile%\AppData\Local\Arduino15

      4. In the Arduino IDE go to Tools-> Board and select Spresense.

      Do you use automatic updates in the Arduino IDE?

      BR

      posted in Spresense
      K
      KamilTomaszewski
    • RE: Questions about spresense-aruino-compatible

      Hello @ahoudeau

      I found a solution. The problem was that there is no zip command in the default installation of MSYS2. You must install an additional package.

      To do this run this command from MSYS2:

      $ pacman -S zip
      

      After installing this package you should no longer have a problem with the prepare_arduino.sh script.

      BR

      posted in Spresense
      K
      KamilTomaszewski
    Developer World
    Copyright © 2019 Sony Corporation. All rights reserved.
    • Contact us
    • Cookies
    • Legal