Serial.print() sometimes does not work

Status
Not open for further replies.

VicPi

Member
Hello (I'm french, so I not really speak english, thanks google translate ^^) !

In order to test the serial port, I upload this sketch on my Teensy 3.2 Pins :

Code:
/* Simple "Hello World" example.

   After uploading this to your board, use Serial Monitor
   to view the message.  When Serial is selected from the
   Tools > USB Type menu, the correct serial port must be
   selected from the Tools > Serial Port AFTER Teensy is
   running this code.  Teensy only becomes a serial device
   while this code is running!  For non-Serial types,
   the Serial port is emulated, so no port needs to be
   selected.

   This example code is in the public domain.
*/

void setup()
{
  Serial.begin(9600); // USB is always 12 Mbit/sec
}

void loop()
{
  Serial.println("Hello World...");
  delay(1000);  // do not print too fast!
}

..and it works perfectly.

Except that I uploaded this sketch and this time, nothing appears on the serial monitor :

Code:
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include <HMC5883L.h>
#include "Wire.h"

#define DOUT_TRIGGER   8
#define DIN_ECHO       9
#define DIN_ON         4

boolean ON;

HMC5883L compass;
MPU6050 mpu;

bool dmpReady = false;  
uint8_t mpuIntStatus;   
uint8_t devStatus;      
uint16_t packetSize;    
uint16_t fifoCount;     
uint8_t fifoBuffer[64];

Quaternion q;           
VectorFloat gravity;   
float ypr[3];     

int tempsActif   = 150;
int tempsInactif = 1;
float distance   = 0;

volatile bool mpuInterrupt = false;
void dmpDataReady() 
{
    mpuInterrupt = true;
}

void setup() 
{    

    Serial.begin(115200);
    Wire.begin();    
    
    pinMode(DOUT_TRIGGER, OUTPUT);
    pinMode(DIN_ECHO, INPUT);
    pinMode(DIN_ON, INPUT_PULLUP);
    
    mpu.initialize();
    devStatus = mpu.dmpInitialize();
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788);
    
    if (devStatus == 0) 
    {
        mpu.setDMPEnabled(true);
        attachInterrupt(4, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
    } 
    else 
    {        
        Serial.print(devStatus);
        Serial.println(F(")"));
    }   
    
    mpu.setI2CBypassEnabled(true); 
    compass = HMC5883L(); 
    setupHMC5883L();
}

void loop(){
  ON = digitalRead(DIN_ON);
  if(1){
    if (!dmpReady) return;
    while (!mpuInterrupt && fifoCount < packetSize){}
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();
    fifoCount = mpu.getFIFOCount();
    if ((mpuIntStatus & 0x10) || fifoCount == 1024){
        mpu.resetFIFO();
    } 
    else if (mpuIntStatus & 0x02){
      while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
      mpu.getFIFOBytes(fifoBuffer, packetSize);
      fifoCount -= packetSize;
      mpu.dmpGetQuaternion(&q, fifoBuffer);
      mpu.dmpGetGravity(&gravity, &q);
      mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);  
      
      //Serial.print("Phi: ");
      Serial.println(ypr[2] * 180/M_PI);
      
      if (ypr[2] * 180/M_PI<-20)
      {
        //keyboard.press('k');
      }
      else if (ypr[2] * 180/M_PI>20)
      {
        //keyboard.press('m');
      }
      if (ypr[1] * 180/M_PI<-25)
      {
        //keyboard.press('l');  
      }
      else if (ypr[1] * 180/M_PI>10)
      {
        //keyboard.press('o');
      }
      if (ypr[1] * 180/M_PI<-5 && ypr[1] * 180/M_PI>-20 && ypr[2] * 180/M_PI>-15 && ypr[2] * 180/M_PI<15)
      {
        float heading = getHeading();
        if (heading<290 && heading>200)
        {
          //keyboard.press('q');  
        }
        else if (heading<200 && heading<350)
        {
          //keyboard.press('d');
        }    
      }
      if (distance>14 && distance <60)
      {
        //keyboard.press('z');
      }
      else if (distance<6)
      {
        //keyboard.press('s');
      }   
      else if (distance>60)
      {} 
      delay(tempsActif);
      
      digitalWrite(DOUT_TRIGGER, LOW);
      delayMicroseconds(2);
      digitalWrite(DOUT_TRIGGER, HIGH);
      delayMicroseconds(10);
      digitalWrite(DOUT_TRIGGER, LOW);
      distance= pulseIn(DIN_ECHO, HIGH) / 58.0;
      //keyboard.releaseAll(); 
    }
    delay(tempsInactif);
  }
}

void setupHMC5883L()
{
 int error; 
 error = compass.SetScale(1.3);
 if(error != 0) Serial.println(compass.GetErrorText(error));
 error = compass.SetMeasurementMode(Measurement_Continuous);
 if(error != 0) Serial.println(compass.GetErrorText(error));
}

float getHeading()
{
 MagnetometerScaled scaled = compass.ReadScaledAxis();
 float heading = atan2(scaled.YAxis, scaled.XAxis);
 if(heading < 0) heading += 2*PI;
 if(heading > 2*PI) heading -= 2*PI;
 return heading * RAD_TO_DEG; 
}

What do I have to do if I want solve this problem ?

There is no error message, the upload of the program works well, but there is nothing on the serial monitor.

The teensy is only connected to a chip GY-87 according to the following hook :

Teensy 3.2 <---> GY-87

3.3V (250 mA max) <---> 3.3V
AGND <---> GND
A5 (SCL0) <--> SOL
A4 ( SDA0) <---> SDA
2 <---> INTA


My pc is running on windows 10 (anniversary update)

Thank you very much in advance ! :)
 
One common problem with using i2c on Teensy is that you need to add pull-up resistors between each of the A4 and A5 pins and ground. The general recommendation is for 5v systems is for 4.7K resistors, but I've seen other places that recommend 2.2K resistors for 3.3v systems. Here is a wiring diagram for hooking up a MCP23017 that shows where the pull-ups go:
mcp20317-i2c.jpg


Also, you hooked up AGND. You should probably hook up GND or ground instead (ground is pin 0 on the other row of pins from 3.3v/agnd, but there is also a ground pin on the set of 5 pins in the back of the Teensy). AGND is meant for analog input devices: https://forum.pjrc.com/threads/110-GND-vs-AGND.
 
thank you very much for your quick response.

1 / So if I apply both your advice, it is sure that my program will work well? Or it could still be another problem?

2/ is there a more discreet solution, small? I just want to address this worry, I will not necessarily additional inputs and outputs

3 / should I change something in my code if I use MCP23017 for example?

I want something easy (and fast !)to implement, I dont have many skills in electronics.

once again, thank you MichaelMeissner :)
 
Last edited:
Add a while statement after serial begin to wait for instantiation of the Serial object.
Code:
  Serial.begin(115200);
  while(!Serial);


Pete
 
Sometimes it implies that your Serial.print statement is not being executed.

Try adding some more print statements. Like maybe the MPU initialize call is hanging or faulting. So try adding the stuff like el_supremo mentioned, plus maybe a small delay, then add a few more print statements, like maybe one just after the !serial and delay, maybe like add a couple of Prints bracketing the call: mpu.initialize();
Maybe one after the next call...

This way you see if you have a print like: Serial.println("Before mpu.initialize");
and it shows up, and a print like: Serial.println("After mpu.initialize"); after the call and it does not show up, then you know problem was probably in that call.

If nothing shows up still, then maybe problem with a constructor for some object...
 
I always try to add it, still dont work :(

While I do not have these devices, there are a couple o thing I would do/try
first put some delay as el_supremo said and print out some statement, say 'welcome to test program'
more important put a small delay (delay(100); or so) after Wire.begin(); as Teensy is too fast for most I2C devices and follow on commands may corrupt devices state machine.

put some print out into setup(), to see if and where program goes into loop
try to understand if loop is executed
 
Last edited:
After this instruction " while (!mpuInterrupt && fifoCount < packetSize){}", the Serial.print doest work !

(sorry for my probably bad english, tell me if you dont understand me :) )
 
Actually take a look at your code.

Where is fifoCount set? The system probably initializes it to zero. And I don't believe that anything behind the scenes is updating it.
 
I don't no where it is/if it really exist. I dont believe too. It is not me which has code it. So what I have to add at my code to set/update fifocount, in others words, to fix my issue ?

maybe here : packetSize = mpu.dmpGetFIFOPacketSize(); ?
 
Last edited:
Sorry, I did not write it either...

But if it were me, I would probably pattern that line after a line farther in the code:
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
Note: but you probably want to check the interrupt flag variable as well
 
If I understood corectly, you tell what it takes remplace the line :

while (!mpuInterrupt && fifoCount < packetSize){}

by it : while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();


and it works !!!Thank you very much, I no longer believed
 
thank you very much for your quick response.

1 / So if I apply both your advice, it is sure that my program will work well? Or it could still be another problem?

2/ is there a more discreet solution, small? I just want to address this worry, I will not necessarily additional inputs and outputs

3 / should I change something in my code if I use MCP23017 for example?

I want something easy (and fast !)to implement, I dont have many skills in electronics.

once again, thank you MichaelMeissner :)

I was just using the image I found via a google search of how to wire a pull-up resistor. Basically, you need to add one 2.2K-4.7K resistor between the A4 pin and the 3.3v pin. You need to add another 2.2K-4.7K resistor between the A5 pin and the 3.3v pin. Otherwise it is likely that your i2c devices will not be able to connect to your Teensy. You only need one pair of pull-up resistors on the i2c bus, so if your device has the resistors, you don't need to add additional ones. The AVR processors (such as the Arduino Uno/Leonardo and Teensy 2.0) have internal pull-up resistors that the library can enable and they don't always need external pull-up resistors. The Teensy (and presumably other Arm Cortex processors) need pull-up resistors.

The value of the resistor can vary based on the bus layout, number of devices, speed of the i2c bus, etc. For simple i2c layouts, 2.2K or 4.7K resistors are typically used (4.7K is the typical value for 5v systems, 2.2K is more typical for 3.3v systems). If you have a lot of devices on the i2c bus, longer wires, or you are operating the devices at a higher speed than the default, you may need to tune the resistors you use for the i2c bus. But, I would start out with one of the default values.

There is an example (Wire->Scanner I believe) that you can load on your Teensy, and it will tell you if the Teensy can see the i2c devices. If the scanner finds your i2c devices, then you probably don't need to do anything. If it can't see the devices, add the pull-up resistors, and see if it can see the devices. If it still can't see the devices, then you will need more advanced debugging.
 
I was just using the image I found via a google search of how to wire a pull-up resistor. Basically, you need to add one 2.2K-4.7K resistor between the A4 pin and the 3.3v pin. You need to add another 2.2K-4.7K resistor between the A5 pin and the 3.3v pin. Otherwise it is likely that your i2c devices will not be able to connect to your Teensy. You only need one pair of pull-up resistors on the i2c bus, so if your device has the resistors, you don't need to add additional ones. The AVR processors (such as the Arduino Uno/Leonardo and Teensy 2.0) have internal pull-up resistors that the library can enable and they don't always need external pull-up resistors. The Teensy (and presumably other Arm Cortex processors) need pull-up resistors.

The value of the resistor can vary based on the bus layout, number of devices, speed of the i2c bus, etc. For simple i2c layouts, 2.2K or 4.7K resistors are typically used (4.7K is the typical value for 5v systems, 2.2K is more typical for 3.3v systems). If you have a lot of devices on the i2c bus, longer wires, or you are operating the devices at a higher speed than the default, you may need to tune the resistors you use for the i2c bus. But, I would start out with one of the default values.

There is an example (Wire->Scanner I believe) that you can load on your Teensy, and it will tell you if the Teensy can see the i2c devices. If the scanner finds your i2c devices, then you probably don't need to do anything. If it can't see the devices, add the pull-up resistors, and see if it can see the devices. If it still can't see the devices, then you will need more advanced debugging.


Thanks for the details ! :) I tested th scanner I2C , and I got that result :

Device found at address 0x68 (DS1307,DS3231,MPU6050,MPU9050,MPU9250,ITG3200,ITG3701,LSM9DS0,L3G4200D)
Device found at address 0x77 (BMP085,BMA180,BMP280,MS5611)

But, my GY-87 chip contain also a HMC5883L, but this line doesnt appear : Serial.print(F("LSM303D,HMC5883L,FXOS8700,LIS3DSH"));
Indeed, in my sketch everything work perfectly, except the calcul of the heading which necessite the HMC5883L

What I have to do to solve that issue ? :/

Also, I have a new problem, I don't know if you could help me :/
A while ago, I used a sketch which applie a complementary filter to the euler angles (yaw, pitch, roll). with a gy-521 (which contain a mpu6050). But I try this sketch with my Teensy 3.2 and it is doesnt work well, indeed, the angles yaw, pitch and roll are equal to 0 :/ How can I adapt that skecth to my teensy ? Actually, I would like rather adapt that sketch to my teensy + gy-87 and not teensy + gy-521 !

The code is very long (because there are lots of #define..) so it is available there under the name : "GY_521_send_serial" :

http://www.geekmomprojects.com/gyroscopes-and-accelerometers-on-a-chip/


Thank you guys again for your fast answers, that's very nice of you, and sorry for the potential spelling mistakes :/

Tell me if you want more precision, if my explaination is not very clear !



(Actually, I just want a sketch who shows the yaw pitch roll angles filtered with a complementary filter, I understand the principe of that filter, but I don't know which function I have to use to pick up the angle from gyroscope for example )
 
Last edited:
I have a similar problem: I have two new boards (Teensy 3.2 and LC) and I can't get the Serial.print() output on a terminal console (while using the USB serial emulation).

The boards seem OK as I can upload and run any sketch. I'm using the same USB connection (cable) for uploading thus I won't blame the USB cable (I've tried three of them though).

I've tried both the Arduino serial console and other serial terminals (picocom, moserial etc). Btw, I'm using linux (xubuntu).

I have to mention that I'm using serial emulation (USB Type: "Serial") and, at the beginning of these tests, I've got some random outputs from Serial.print() commands (it only printed once or twice, although there was a continuous printing loop, every second).

What could be the problem? I've had some troubles with my laptop (linux) in the past but all USB ports are OK.

I've tried various port settings (8/1/N, 9600-115200, hw/sw and so on) with no success. Any help are greatly appreciated.
 
Hi Pete,

This is the whole sketch:

Code:
void setup()
{
  Serial.begin(115200);
  while(!Serial);
  pinMode(13, OUTPUT);
}

void loop()
{
  Serial.println("test");
  digitalWrite(13, HIGH);
  delay(20);
  digitalWrite(13, LOW);
  delay(2000);
}

The LED is blinking thus the loop() is working. That means the serial is working too (the program has passed the "while(!Serial)" statement in the setup() routine).
 
I've added this:

Code:
void loop()
{
  [B]Serial.flush();[/B]
  Serial.println("test");
  [B]Serial.send_now();[/B]
  digitalWrite(13, HIGH);
  delay(20);
  digitalWrite(13, LOW);
  delay(2000);
}

.. but it only printed "test" once (randomly) then.. nothing.
 
I ran the following sketch:

Code:
#include <usb_serial.h>

int8_t usb_exit;

void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  delay(2000);
  usb_exit = usb_serial_putchar('x');
  digitalWrite(13, usb_exit + 1); 
  delay(20);
  digitalWrite(13, LOW);
}

The LED only blinks twice (thus the exit code of the "usb_serial_putchar('x')" statement was "0' (success)) then.. nothing.

It means there is an error with "usb_serial_putchar()" command (it returns "-1"). Is there any other test I should run to debug these USB errors?
 
Another test:

Code:
#include <usb_serial.h>

usb_serial_class myUSB;

void setup()
{
  myUSB.begin(115200);
  pinMode(13, OUTPUT);
}

void loop()
{
  delay(2000);
  myUSB.write('x');  
  digitalWrite(13, HIGH);
  delay(20);
  digitalWrite(13, LOW);
}

No luck: the LED is blinking but nothing is printed on terminal console.
 
I've just loaded your last sketch (msg #22) on a Teensy LC and it is printing to the serial monitor on a Windows 7 PC.

Pete
 
Thanks, Pete. Looks like there's a problem with the linux driver(?) although uploading a sketch (and serial port detection) works just fine.

I'll try later on another PC (linux).
 
@someteen

Are you overclocking your Teensy? My Teensy 3.0 doesn't work reliably at 96MHz.

You don't need a Terminal program. A simple "cat /dev/ttyACM0" would do. Your sketch #22 is working fine with my Gentoo system. What does your dmesg output say?
 
Status
Not open for further replies.
Back
Top