TinyCircuits

Recent Posts

Pages: 1 2 [3] 4 5 ... 10
21
TinyDuino / Re: how do I change the address resistors for two 9 axis IMU?
« Last post by Guzmanxy on September 19, 2018, 11:18:33 PM »
I really want to know How does the site crawl and most of the information about it is enough to explain?
22
User Projects / Code Examples / Re: 9 Axis IMU + MicroSD
« Last post by PioneeringStar on September 18, 2018, 06:05:42 AM »
I'm currently developing a 9-axis data-logger. This uses a tinyscreen+, wifi, 9-axis imu and an sd-card. This currently works, but needs a change to manage file sizes.

The Arduino SD card writes to FAT32 only, and can only create files with 8 dot 3 filenames. File size is a concern to me as I'm trying to ensure I get at least 25 samples per second. This is going to create large file sizes, and the open-write data-close are going to get slower as the file get bigger.


#include <Wire.h>
#include <SPI.h>
#include <TinyScreen.h>
#include <WiFi101.h>
#include <RTCZero.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "RTIMUSettings.h"
#include "RTIMU.h"
#include "RTFusionRTQF.h"
#include <SD.h>

//---------------------------------------------------------------

//Set up the WiFi
char ssid[] = "";        // your network SSID (Name)
char pass[] = "";          // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;       // the WiFi radio's status
bool WifiShieldPresent = false;
bool CalculatingGyro = false;
bool FirstTimeThrough = true;      //This is so we can do a bunch of stuff on the initial run after turning on

//Set up the TinyScreen+
//Library must be passed the board type
//TinyScreenDefault for TinyScreen shields
//TinyScreenAlternate for alternate address TinyScreen shields
//TinyScreenPlus for TinyScreen+
TinyScreen display = TinyScreen(TinyScreenPlus);

//Create a file object for writing out data to the SD card
File myFile;

//Tell the SD card library that the SD card controller is on pin 10 of the Arduino
const int Chipselect = 10;

//Set up the Filename for storing X/Y/Z degree data
String MyFileName = "";
String OutputVal = "";

//Set up the IMU (Inertial Motion Unit) 9-axis chip
RTIMU *imu;                                           // the IMU object
RTFusionRTQF fusion;                                  // the fusion object
RTIMUSettings settings;                               // the settings object

// NTP (Network Time Protocol) Setup
// You can specify the time server pool and the offset, (in seconds)
// additionaly you can specify the update interval (in milliseconds).
// NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
WiFiUDP ntpUDP;
NTPClient NTPtimeClient(ntpUDP);
NTPClient timeClient(ntpUDP, "0.uk.pool.ntp.org", 3600, 60000); //Change this to local network NTP server IP address if neeeded

//Create an RTCZero object to talk to the onboard clock
RTCZero rtc;

//  DISPLAY_INTERVAL sets the rate at which results are displayed
#define DISPLAY_INTERVAL  35                         // interval between pose displays - default was 300
unsigned long lastDisplay;
unsigned long lastRate;

int sampleCount;
//---------------------------------------------------------------

void setup() {
  //Start the Wire object. We need this in order to talk with the IMU and other devices on the bus.
  Wire.begin();

  //Initialise the TinyScreen+ Display
  display.begin();                        //Start the display object
  display.setBrightness(5);                  //Turn down the brightness so we don't burn the OLED
  display.setFont(thinPixel7_10ptFontInfo);      //Nice, readable, font size
  display.fontColor(TS_8b_White, TS_8b_Black);  //Set the font color, font background
  display.on();                                 //Turns TinyScreen display on
  display.clearScreen();                  //Clear the screen
  display.setCursor(1, 1);                  //Put the cursor in the top left. A line is about 10 pixels setCursor(X,Y)

  //Start the SD-Card
  pinMode(10, OUTPUT);                     //Set pin 10 to output
  display.println("Initializing");
  display.setCursor(1, 10);                  //Move the cursor down 1 line
  display.println("SD card...");
  delay(2000);
  display.clearScreen();

  SD.begin(10);

  int errcode;

  //Make DAMN sure that the filename is blank.
  MyFileName = "";
 
  //Set up the Wifi
  //-------------------------------------
  //Set up the WiFi pins, as the tinyduino wifi shield are different from the defaults
  WiFi.setPins(8, 2, A3, -1); // VERY IMPORTANT FOR TINYDUINO
 
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
     display.setCursor(1, 1);
     display.print("WiFi shield");
     display.setCursor(1, 10);
     display.print("not present");
     // don't continue:
     //while (true);
  }
  else {
     WifiShieldPresent = true;
  }
 
  if (WifiShieldPresent == true) {
     // attempt to connect to WiFi network:
     while (status != WL_CONNECTED) {
      display.clearScreen();
      display.setCursor(1,1);
      display.println("Attempting");
      display.setCursor(1,10);
      display.println("to connect WIFI: ");
      display.setCursor(1,20);
      display.println(ssid);
      // Connect to WPA/WPA2 network:
      status = WiFi.begin(ssid, pass);

      // wait 10 seconds for connection:
      delay(10000);
  }
 
  //Get the assigned IP Address
  IPAddress ip = WiFi.localIP();

  // you're connected now, so show a message and the IP Address:
  display.clearScreen();
  display.setCursor(1,1);
  display.println("Connected!");
  display.setCursor(1,10);
  display.print("IP: ");
  display.println(ip);

  //Start the Onboard Realtime Clock
  rtc.begin();

  //Start the Network Time Protocol (NTP) Client
  //We need the WiFi for this to work, but we assume it has
  NTPtimeClient.begin();
  NTPtimeClient.forceUpdate();
  display.setCursor(1, 20);

  //Sync the time between the NTP server and the onboard Realtime Clock (RTC)
  //If the RTC is already configured, don't bother. The small battery doesn't last long,
  //so we can 'assume' that if the RTC is set, then it sync'd recently.
  while ((rtc.isConfigured() == false) || (rtc.getYear() == 00)) {
     display.clearScreen();
     display.setCursor(1, 1);
     display.print("NTP Sync");
     rtc.setTime(NTPtimeClient.getHours(), NTPtimeClient.getMinutes(), NTPtimeClient.getSeconds());
     rtc.setEpoch(NTPtimeClient.getEpochTime());
  }

  //Quickly show the time on-screen before Getting into the tracking
  display.clearScreen();
  display.print(NTPtimeClient.getFormattedTime());
  display.setCursor(1, 30);
  display.print(rtc.getDay());
  display.print("/");
  display.print(rtc.getMonth());
  display.print("/");
  display.print(rtc.getYear());

  //Assemble the first filename to use
  CreateFilename();
  display.setCursor(1, 40);
  display.println(MyFileName);


  delay(10000); //Wait 10 seconds
  display.clearScreen();
  }
 
  //Initialise the IMU
  display.clearScreen();
  display.setCursor(1, 1);
  imu = RTIMU::createIMU(&settings);                        // create the imu object
  display.print("ArduinoIMU");
  display.setCursor(1, 10);
  display.print("starting");
  if ((errcode = imu->IMUInit()) < 0) {
     display.clearScreen();
     display.setCursor(1, 1);
     display.print("Failed to init");
     display.setCursor(1, 20);
     display.print("IMU: ");
     display.println(errcode);
  }

  display.clearScreen();
  display.setCursor(1, 1);
  if (imu->getCalibrationValid()) {
     display.print("Using compass");
     display.setCursor(1, 20);
     display.print("calibration");
  }
  else {
     display.setCursor(1, 1);
     display.print("No valid ");
     display.setCursor(1, 10);
     display.print("compass calibration");
     display.setCursor(1, 20);
     display.print("data");
  }
  lastDisplay = lastRate = millis();
  sampleCount = 0;
  delay(5000); //Wait 5 seconds
  display.clearScreen();

  // Slerp power controls the fusion and can be between 0 and 1
  // 0 means that only gyros are used, 1 means that only accels/compass are used
  // In-between gives the fusion mix.

  fusion.setSlerpPower(0.02);

  // use of sensors in the fusion algorithm can be controlled here
  // change any of these to false to disable that sensor

  fusion.setGyroEnable(true);
  fusion.setAccelEnable(true);
  fusion.setCompassEnable(true);

}

void loop() {
  // put your main code here, to run repeatedly:
   unsigned long now = millis();
   unsigned long delta;

   //Start reading the IMU (Inertial Motion Unit)
  if (imu->IMURead()) {                                // get the latest data if ready yet
     fusion.newIMUData(imu->getGyro(), imu->getAccel(), imu->getCompass(), imu->getTimestamp());
     sampleCount++;
     if ((delta = now - lastRate) >= 1000) {
        if (imu->IMUGyroBiasValid())
        {
           display.clearScreen();
           display.setCursor(1, 15);
           if (FirstTimeThrough == true) {
            display.print("Gyro Calibrated");
           }
           CalculatingGyro = false;
        }
        else
        {
           display.setCursor(1, 15);
           display.print("Calculating gyro");
           display.setCursor(1, 25);
           display.print("Don't move IMU!!");
           CalculatingGyro = true;
        }
        sampleCount = 0;
        lastRate = now;
     }
    
     if (CalculatingGyro == false) {
        if (FirstTimeThrough == true) {
         display.clearScreen();
         FirstTimeThrough = false;
        }
        if ((now - lastDisplay) >= DISPLAY_INTERVAL) {
           lastDisplay = now;
           RTVector3 accelData = imu->getAccel();
           RTVector3 gyroData = imu->getGyro();
           RTVector3 compassData = imu->getCompass();
           RTVector3 fusionData = fusion.getFusionPose();
           //displayAxis("Accel:", accelData.x(), accelData.y(), accelData.z());        // accel data
           //displayAxis("Gyro:", gyroData.x(), gyroData.y(), gyroData.z());            // gyro data
           //displayAxis("Mag:", compassData.x(), compassData.y(), compassData.z());    // compass data
           //displayDegrees("Fusion Position:", fusionData.x(), fusionData.y(), fusionData.z());   // fused output
           WriteToFile(fusionData.x(), fusionData.y(), fusionData.z(), accelData.x(), accelData.y(), accelData.z(), gyroData.x(), gyroData.y(), gyroData.z(), compassData.x(), compassData.y(), compassData.z());
        }
     }
  }


}

void displayAxis(const char *label, float x, float y, float z)
{
   OutputVal = "";
   OutputVal = label;
   OutputVal = OutputVal + (",X:");
   OutputVal = OutputVal + (x);
   OutputVal = OutputVal + (",Y:");
   OutputVal = OutputVal + (y);
   OutputVal = OutputVal + (",Z:");
   OutputVal = OutputVal + (z);
   OutputVal = OutputVal + (",T:" + NTPtimeClient.getFormattedTime());
   OutputVal = OutputVal + ":";
   OutputVal = OutputVal + ((int(millis() / 10) % 100));

   // open the file. note that only one file can be open at a time,
   // so you have to close this one before opening another.
   myFile = SD.open(MyFileName, FILE_WRITE);

   //If the file was opened properly
   if (myFile) {
      //Write the data out
      myFile.println(OutputVal);
      //Close the file
      myFile.close();
   }
   else {
      display.setCursor(30, 15);
      display.print("Error writing to file");
   }

}

void WriteToFile(const float Fusionx, float Fusiony, float Fusionz, float Accelx, float Accely, float Accelz, float Gyrox, float Gyroy, float Gyroz, float Compassx, float Compassy, float Compassz)
{
   OutputVal = "";
   OutputVal = "Fusion Position:";
   OutputVal = OutputVal + (",X:");
   OutputVal = OutputVal + (Fusionx * RTMATH_RAD_TO_DEGREE);
   OutputVal = OutputVal + (",Y:");
   OutputVal = OutputVal + (Fusiony * RTMATH_RAD_TO_DEGREE);
   OutputVal = OutputVal + (",Z:");
   OutputVal = OutputVal + (Fusionz * RTMATH_RAD_TO_DEGREE);
   OutputVal = OutputVal + ",Accelerometer:";
   OutputVal = OutputVal + (",X:");
   OutputVal = OutputVal + (Accelx);
   OutputVal = OutputVal + (",Y:");
   OutputVal = OutputVal + (Accely);
   OutputVal = OutputVal + (",Z:");
   OutputVal = OutputVal + (Accelz);
   OutputVal = OutputVal + ",Gyroscope:";
   OutputVal = OutputVal + (",X:");
   OutputVal = OutputVal + (Gyrox);
   OutputVal = OutputVal + (",Y:");
   OutputVal = OutputVal + (Gyroy);
   OutputVal = OutputVal + (",Z:");
   OutputVal = OutputVal + (Gyroz);
   OutputVal = OutputVal + ",Compass:";
   OutputVal = OutputVal + (",X:");
   OutputVal = OutputVal + (Compassx);
   OutputVal = OutputVal + (",Y:");
   OutputVal = OutputVal + (Compassy);
   OutputVal = OutputVal + (",Z:");
   OutputVal = OutputVal + (Compassz);
   OutputVal = OutputVal + (",Timestamp:" + NTPtimeClient.getFormattedTime());
   OutputVal = OutputVal + ":";
   OutputVal = OutputVal + ((int(millis() / 10) % 100));

   // open the file. note that only one file can be open at a time,
   // so you have to close this one before opening another.
   myFile = SD.open(MyFileName, FILE_WRITE);

   //If the file was opened properly
   if (myFile) {
      //Write the data out
      myFile.println(OutputVal);
      //Close the file
      myFile.close();
   }
   else {
      display.setCursor(30, 15);
      display.print("Error writing to file");
   }


}

void CreateFilename()
{
   int Day = rtc.getDay();
   int Hours = rtc.getHours();
   int Minutes = rtc.getAlarmMinutes();

   //Note. Filenames CANNOT be more than 8.3 characters
   MyFileName = "";
   //MyFileName = MyFileName + rtc.getMonth();
   MyFileName = MyFileName + Day;
   MyFileName = MyFileName + "_" + Hours;
   
   //We need to add a zero to bring it to 24hr format
   if (Minutes < 10) {
      MyFileName = MyFileName + "0";
   }

   MyFileName = MyFileName + Minutes;
   MyFileName = MyFileName + ".csv";
}
23
TinyDuino / Re: Serial.read baud-rate issues...
« Last post by Bullwinkle on September 17, 2018, 07:01:25 PM »
Well, perhaps I wasn't clear when I said "knocking my port speed down to 9600...": I should have said "I changed both the port speed AND the baud-rate specified in the code" from 115200 to 9600.  There was No mismatch at any time.
As for conflicts, there are none.  Also, I'm not using a hub or intermediate USB connection; I suspect a hardware issue of some sort, but don't have time to worry about it at this point.  Still, would be nice to understand what's going on.
24
Hey guys

I build a barometer that I can use for skydiving that mounts into my helmet.

The program works fine on a regular TinyScreen and now I wanted to change to a TinyScreen+ because it take less space inside the helmet.

The altimeter readings I get on the barometer are totally different on the TinyScreen+ and make no sense.
I have no idea what I do wrong....!?
I shortened the program to the very basics to find out what the problem could be. Other than the deleting the "Wire.begin();" statement and changing the "TinyScreen display = TinyScreen(TinyScreenPlus);"
is there anything else I need to change in the communication?
Any help is very much appreciated.  Cheers Dan
25
General Discussion / Re: BMP file on Tinyscreen
« Last post by OO-MCP on September 16, 2018, 03:22:23 PM »
Well, It's easy to use and I'm proud to see the picture on the tiny screen, but...I know it's a sketsh for video and i use it for a picture. With only one picture on the SD card there's no problem at all. Whenever there are more then one pictures on the SD card, the program wil display them one by one...in less then a second. So that's not going like I wish.
I see 2 lines in the code with delay (100) So I try to change the milisec with a bigger number. It does absolutly nothing to the speed in displaying the TSV pictures on the screen. How can i slow this down?
26
General Discussion / had to try 3 different usb cables
« Last post by littlejohn on September 15, 2018, 04:31:56 PM »
just FYI, I was about to ask for help becuase my tinyscreen+ wasn't showing up at all when I plugged it in. I had tried two different USB micro cables on 2 different computers. Then I tried a 3rd cable, and now it is working fine. Touchy cables or touchy connector, I wonder.
27
General Discussion / Re: BMP file on Tinyscreen
« Last post by OO-MCP on September 13, 2018, 12:15:34 PM »
Thank you Hunter. That part is ok now. I was able to play a TSV file on the display. My next step is now trying to switch a tsv file on a buttonpush. Going to play with the code before I'm going to ask for help :-)
Anyhow, I love it...great fun in trying to achieve something :-) :-) :-)
28
General Discussion / Re: BMP file on Tinyscreen
« Last post by HunterHykes on September 12, 2018, 04:56:54 PM »
You may want to check out our .tsv video converter tutorial (https://tinycircuits.com/blogs/learn/tsv-video-converter-tutorial). The process detailed in the tutorial works for displaying videos and images from a micro SD card. In my experience, still images just have to be saved as .gif files in order for the program to work properly. This can easily be done with other file formats by opening them in an image editing program such as Paint and saving them as a .gif file. After that, simply follow the tutorial above and you should be able to figure it out!

I hope this helps.

-Hunter
29
General Discussion / BMP file on Tinyscreen
« Last post by OO-MCP on September 12, 2018, 10:55:09 AM »
Hi there. I'm trying to show a BMP file on the Tinyscreen, but all I get is...Well, nothing. No error messadge and black screen. Uploading the code is going well, but with no result, no display from the BMP file from the SD Card.
The code that I'm using is from Codebender https://codebender.cc/sketch:86070#TinyScreen_Bitmap_Display.ino
Changed both 1.bmp into the filenames on the SD Card. My hardware is the Tinyscreen with USB, batteryplug, buttons and switch and the SD Card print.
Displaying text is working well and I know how to write that code now.
Can anyone help me here?
Just pointing my nose in the correct direction would be fine.
Doing my best...but hey...maybe I'm too old to learn all this :-)

30
TinyDuino / Re: Serial.read baud-rate issues...
« Last post by lennevia on September 06, 2018, 10:25:02 AM »
To answer your question, it's possible both hardware and software can cause garbage printing issues. The common software issue, as you saw, is the mismatch of baud rates between two communicating devices. The different rates of communication essentially become foreign languages as the data is receiving and transmitting independently and there is chaos, which gives us garbage.
A common hardware issue can occur when trying to communicate with more than two serial devices on one serial bus. When two devices communicate back and forth on one line, there is some order. When there are multiple devices communicating on one line, there is chaos, all devices could be speaking at once or none at all, again producing visual garbage on the Serial Monitor.
Pages: 1 2 [3] 4 5 ... 10