How to make Built in LED blink systematically? - arduino
I am trying to make my built in LED on my arduino blink every 1 second while recording my data and putting it in the EEPROM, but I am not sure how to do that. I am supposed to print data to the EEPROM every minute, until the EEPROM is full and while that is going on my built in LED should blink for approx 1 second. My problem seems to be that I am setting a delay to delay how long the data is stored on the EEPROM, but it is also affecting the time it takes for my LED to blink as it is waiting to blink as the data is stored. Any help would be appreciated, the code is below:
#include<EEPROM.h>
const int SWITCH = 4;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(SWITCH, INPUT_PULLUP);
}
void loop() {
// put your main code here, to run repeatedly:
int addr = 0;
float v;
float c;
int t = 0;
int r = analogRead(0);
if (digitalRead(SWITCH) == LOW) {
Serial.println("----Recording----");
while (addr <= 1024) {
Serial.println(r);
EEPROM.put(addr, r);
addr = addr + 2;
delay(600);
}
while (true);
}
else {
Serial.println("----Replaying----");
Serial.println("Time(s), Temp(C)");
while (addr <= 1024) {
t = t + 1;
EEPROM.get(addr, r);
addr = addr + 2;
v = r * 5.0 / 1024.0;
c = 100 * (v - 0.5);
Serial.print(t * 60);
Serial.print("\t");
Serial.println(c);
delay(1000);
}
while (true);
}
}
Related
Stroboscope with Arduino
first sorry for my bad english I'm a student and I want to make a Stroboscope with Arduino for my school project The frequency is variable between 10hz to 3000 hz and it changes using a rotary encoder that when normally rotate the encoder 1 step frequency \pm 1hz and when rotate encoder when it pushed down frequency \pm 100hz and Arduino make a PWM signal on pin 13 and it connect to a high power npn transistor and it turn on and off a 10 watt led I code it using Encoder.h library by Paul Stoffregen and tone() function but I have a PROBLEM I code this program and upload it to Arduino Uno but it doesn't work IDK where is the problem #include <Encoder.h> #define ENCODER_PULSES_PER_STEP 1 int f = 10; int direction; Encoder myEnc(2, 3); int t = 0; void setup() { pinMode(13, OUTPUT); pinMode(4, INPUT_PULLUP); pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); direction = myEnc.read(); } void loop() { if (abs(direction) >= ENCODER_PULSES_PER_STEP) { if (direction > 0) { if (digitalRead(4) == 1) { f++; if (f >> 2500)f = 2500; } else { f = f + 100; if (f >> 2500)f = 2500; } } else { if (digitalRead(4) == 1) { f--; if (f << 10)f = 10; } else { f = f - 100; } } myEnc.write(0); } tone(13, f); }
When your program starts the function setup is executed once. Then in an infinite loop the function loop is executed. As you have direction = myEnc.read(); only in setup you'll only read the encoder once. From the Encoder library's documentation: /* Encoder Library - TwoKnobs Example * http://www.pjrc.com/teensy/td_libs_Encoder.html * * This example code is in the public domain. */ #include <Encoder.h> // Change these pin numbers to the pins connected to your encoder. // Best Performance: both pins have interrupt capability // Good Performance: only the first pin has interrupt capability // Low Performance: neither pin has interrupt capability Encoder knobLeft(5, 6); Encoder knobRight(7, 8); // avoid using pins with LEDs attached void setup() { Serial.begin(9600); Serial.println("TwoKnobs Encoder Test:"); } long positionLeft = -999; long positionRight = -999; void loop() { long newLeft, newRight; newLeft = knobLeft.read(); newRight = knobRight.read(); if (newLeft != positionLeft || newRight != positionRight) { Serial.print("Left = "); Serial.print(newLeft); Serial.print(", Right = "); Serial.print(newRight); Serial.println(); positionLeft = newLeft; positionRight = newRight; } // if a character is sent from the serial monitor, // reset both back to zero. if (Serial.available()) { Serial.read(); Serial.println("Reset both knobs to zero"); knobLeft.write(0); knobRight.write(0); } } Notice the differences between your and their code. Another more simple example from the GitHub repository to satisfy Juraj. /* Encoder Library - Basic Example * http://www.pjrc.com/teensy/td_libs_Encoder.html * * This example code is in the public domain. */ #include <Encoder.h> // Change these two numbers to the pins connected to your encoder. // Best Performance: both pins have interrupt capability // Good Performance: only the first pin has interrupt capability // Low Performance: neither pin has interrupt capability Encoder myEnc(5, 6); // avoid using pins with LEDs attached void setup() { Serial.begin(9600); Serial.println("Basic Encoder Test:"); } long oldPosition = -999; void loop() { long newPosition = myEnc.read(); if (newPosition != oldPosition) { oldPosition = newPosition; Serial.println(newPosition); } } Also note that << is the binary left shift operator, not the less than operator < ! In if (f << 10)f = 10; you'll shift f 10 bits to the left. As this results in a number > 0, which is true, this condition will alway be met. Same for >> which is the bitwise right shift operator, not greater then!
I could not make IRsend from the IRremote library to work
Hello i am using an arduino mkr1000 so send and IR signal using the IRremote library for mkr1000 IRremote library. I am having problems with IRsend. First i used the IRdump example to get the data from my remote button. When i finished this i tried the IRsend example but it seems to be not working. I temporarily replaced with a ordinary LED to show if it is really blinking, but it is not. I have tested the both the ordinary LED and IR LED that they worked. I also think that i have wired the LED correctly according to the example PIN 3 -> LED -> Resistor -> Ground My circuit was further confirmed correct when i upload a sketch that makes it blink. Basically i am trying to send a NEC 32bit signal, 0x2FD807F but i guess they were not able to finish the library of send for mkr1000??? in this post a comment was made with a code but did not really have any detail on how to use it. here is where i am currently at int IR_S = 3; void setup() { pinMode(IR_S,OUTPUT); } void loop() { IR_Sendcode(0x2FD807F); delay(1000); } void IR_Send38KHZ(int x,int bit) //Generate 38KHZ IR pulse { for(int i=0;i<x;i++)//15=386US { if(bit==1) { digitalWrite(IR_S,1); delayMicroseconds(9); digitalWrite(IR_S,0); delayMicroseconds(9); } else { digitalWrite(IR_S,0); delayMicroseconds(20); } } } void IR_Sendcode(uint8_t data) // Send the data { for(int i=0;i<8;i++) { if((data&0x01)==0x01) { IR_Send38KHZ(23,1); IR_Send38KHZ(64,0); } else { IR_Send38KHZ(23,1); IR_Send38KHZ(21,0); } data=data>>1; } }
I while i was waiting for replies i created my own code. I have finished and tested it. It should theoretically work on any arduino. /* This is a code for NEC Infrared Transmission Protocol Transmitter NEC specifications are ~ Carrier Frequency is 38kHz * Logical '0' – a 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1.125ms * Logical '1' – a 562.5µs pulse burst followed by a 1.6875ms space, with a total transmit time of 2.25ms - a 9ms leading pulse burst (16 times the pulse burst length used for a logical data bit) - a 4.5ms space - the 8-bit address for the receiving device - the 8-bit logical inverse of the address - the 8-bit command - the 8-bit logical inverse of the command - a final 562.5µs pulse burst to signify the end of message transmission. Example, If the code recieved from the data dump from the IRremote library is 0x2FD807F -0x02 is address -0xFD is the inverse address -0x80 is the command -0x7F is the inverse command THIS PROGRAM IS A BLOCKING PROGRAM */ #define IR 3 #define CarrierFreqInterval 11 void setup() { pinMode(IR, OUTPUT); digitalWrite(IR, LOW); } void loop() { // unsigned long start = micros(); transmit(0x02FD807F); // unsigned long ends = micros(); // unsigned long delta = ends - start; // Serial.println(delta); delay(500); } void transmit(uint32_t data) { //Function for transmiting the data uint32_t bitcount = 0x80000000; // 9ms pulse burst for (int i = 0; i < 355; i++) { digitalWrite(IR, HIGH); delayMicroseconds(CarrierFreqInterval); digitalWrite(IR, LOW); delayMicroseconds(CarrierFreqInterval); } // 4.5ms space delayMicroseconds(4500); //8bit address,adress inverse,command,command inverse while ( bitcount != 0b0) { if ((data & bitcount) == bitcount) { pulseHIGH(); } else { pulseLOW(); } bitcount = bitcount >> 1; } //final pulse burst for (int i = 0; i < 21; i++) { digitalWrite(IR, HIGH); delayMicroseconds(CarrierFreqInterval); digitalWrite(IR, LOW); delayMicroseconds(CarrierFreqInterval); } } void pulseHIGH() { // Pulse 38KHz good for a LOGIC '1' for (int i = 0; i < 21; i++) { digitalWrite(IR, HIGH); delayMicroseconds(CarrierFreqInterval); digitalWrite(IR, LOW); delayMicroseconds(CarrierFreqInterval); } delay(1); delayMicroseconds(687.5); } void pulseLOW() { // Pulse 38KHz good for a LOGIC '0' for (int i = 0; i < 21; i++) { digitalWrite(IR, HIGH); delayMicroseconds(CarrierFreqInterval); digitalWrite(IR, LOW); delayMicroseconds(CarrierFreqInterval); } delayMicroseconds(562.5); }
Reading and transferring encoder data from slave Arduino to master Arduino over SPI
My goal is to transfer a speed value from an encoder from a slave Arduino to a master Arduino via SPI. I am currently getting zeros on the master side serial print and I'm not sure what I am doing wrong. I have increased the amount of time to wait several times to see if it was a processing time issue but I had it waiting for 100mS with still no change. I know an unsigned int is 4 bytes and I am unsure if a union is the best option in this case seeing I might be overwriting my data due to the separate interrupts but I am unsure. I thought to use a struct since I'll have to move to transferring an array of floats and ints over SPI from various sensors including this encoder later. Below is my code and thank you for any help received: Slave #include "math.h" #define M_PI byte command = 0; const int encoder_a = 2; // Green - pin 2 - Digital const int encoder_b = 3; // White - pin 3 - Digital long encoder = 0; int Diameter = 6; // inches float previous_distance = 0; unsigned long previous_time = 0; void setup (void) { Serial.begin(115200); pinMode(MOSI, INPUT); pinMode(SCK, INPUT); pinMode(SS, INPUT); pinMode(MISO, OUTPUT); // turn on SPI in slave mode SPCR |= _BV(SPE); // turn on interrupts SPCR |= _BV(SPIE); pinMode(encoder_a, INPUT_PULLUP); pinMode(encoder_b, INPUT_PULLUP); attachInterrupt(0, encoderPinChangeA, CHANGE); attachInterrupt(1, encoderPinChangeB, CHANGE); } // SPI interrupt routine ISR (SPI_STC_vect) { union Data{ float f; byte buff[4];} data; byte c = SPDR; data.f = assembly_speed(); command = c; switch (command) { // no command? then this is the command case 0: SPDR = 0; break; // incoming byte, return byte result case 'a': SPDR = data.buff[0]; break; // incoming byte, return byte result case 'b': SPDR = data.buff[1]; break; // incoming byte, return byte result case 'c': SPDR = data.buff[2]; break; // incoming byte, return byte result case 'd': SPDR = data.buff[3]; break; } } void loop (void) { // if SPI not active, clear current command if (digitalRead (SS) == HIGH) command = 0; } void encoderPinChangeA() { encoder += digitalRead(encoder_a) == digitalRead(encoder_b) ? -1 : 1; } void encoderPinChangeB() { encoder += digitalRead(encoder_a) != digitalRead(encoder_b) ? -1 : 1; } float distance_rolled() { float distance_traveled = (float (rotation()) / 8) * PI * Diameter; return distance_traveled; } int rotation() { float eigth_rotation = encoder / 300; return eigth_rotation; } float assembly_speed() { float current_distance = (float (rotation()) / 8) * PI * Diameter; unsigned long current_time = millis(); unsigned long assemblySpeed = (((current_distance - previous_distance) / 12) * 1000) / (current_time - previous_time); // gives ft/s previous_distance = current_distance; previous_time = current_time; return assemblySpeed; } Master #include <SPI.h> void setup (void) { pinMode(MOSI, OUTPUT); pinMode(MISO, INPUT); pinMode(SCK, OUTPUT); pinMode(SS, OUTPUT); Serial.begin (115200); Serial.println (); digitalWrite(SS, HIGH); SPI.begin (); SPI.setClockDivider(SPI_CLOCK_DIV8); } byte transferAndWait (const byte what) { byte a = SPI.transfer (what); delayMicroseconds(10000); return a; } union Data { float f; byte buff[4]; } data; void loop (void) { digitalWrite(SS, LOW); transferAndWait ('a'); data.buff[0] = transferAndWait ('b'); data.buff[1] = transferAndWait ('c'); data.buff[2] = transferAndWait ('d'); data.buff[3] = transferAndWait (0); digitalWrite(SS, HIGH); Serial.print("data.f = ");Serial.print(data.f);Serial.println(" Ft/s"); delay(200); }
Why does the SD card stop logging without error?
The following sketch is for an Arduino Nano clone. It waits for a START command then collects data from an I2C slave, assembles it for logging on an SD card, writes it to the card, prints it to the serial monitor and repeats. I've tested and retested. The SD card logfile ALWAYS stops after logging the header and 3 out of 30 lines of data, but the serial monitor shows all the expected data. Never in any of my tests was an SD write error generated. I'd appreciate any ideas as to why the SD stops logging and how to fix it. Arduino Sketch #include <Wire.h> #include <Servo.h> #include <SD.h> #include <SPI.h> // Uncomment the #define below to enable internal polling of data. #define POLLING_ENABLED //define slave i2c address #define I2C_SLAVE_ADDRESS 9 /* =================================== Arduino Nano Connections ESC (PWM) Signal - Pin 9 (1000ms min, 2000ms max) S.Port Signal - Pin 10 SPI Connections MOSI = Pin 11 MISO = Pin 12 SCLK = PIN 13 I2C Connections SDA = Pin A4 SCL = Pin A5 Start/Stop Switches Start = Pin 2 => INT0 Stop = Pin 3 => INT1 ===================================*/ Servo esc; // Servo object for the ESC - PIN 9 const unsigned long pause = 800; // Number of ms between readings const unsigned long testDelay = 30000; // Number of ms between tests const int CS_pin = 10; // Pin to use for CS (SS) on your board const int Startpin = 2; const int Stoppin = 3; const int readings = 3; // Number of readings to take at every step const int steps = 5; // Number of steps to stop the ESC and take readings const byte HALT = 0; int ESC = 0; int throttle = 0; int increment; volatile bool STOP = 0; volatile bool START = 0; const String header = "% Thr,Thrust,Curr,Volts,RPM,Cell1,Cell2,Cell3,Cell4,Cell5,Cell6"; char buffer0[33]; // Buffer for I2C received data char buffer1[33]; // Buffer for I2C received data String logEntry = " GOT NO DATA "; //52 bytes void setup() { Wire.begin(); Serial.begin(115200); pinMode(Startpin, INPUT_PULLUP); pinMode(Stoppin, INPUT_PULLUP); // Attach an interrupt to the ISR vector attachInterrupt(digitalPinToInterrupt(Startpin), start_ISR, LOW); attachInterrupt(digitalPinToInterrupt(Stoppin), stop_ISR, LOW); esc.attach(9, 1000, 2000); // attaches the ESC on pin 9 to the servo object and sets min and max pulse width esc.write(HALT); // Shut down Motor NOW! increment = 180 / (steps - 1); // Number of degrees to move servo (ESC) per step (servo travel is 0-180 degrees so 180 = 100% throttle) delay(500); Serial.println(" Thrust Meter I2C Master"); //Print program name //Initialize SD Card if (!SD.begin(CS_pin)) { Serial.println("Card Failure"); } Serial.println("Card Ready"); //Write Log File Header to SD Card writeSD(header); Serial.println(header); } void loop() { if (START) { Serial.println("Start Pressed"); while (!STOP) { for (throttle = 0; throttle <= 180; throttle += increment) { for (int x = 0; x < readings; x++) { if (STOP) { esc.write(HALT); // Shut down Motor NOW! Serial.println("Halting Motor"); } else { wait (pause); esc.write(throttle); // increment the ESC wait (200); ESC = throttle * 100 / 180; getData(buffer0); wait (100); getData(buffer1); String logEntry = String(ESC) + "," + String(buffer1) + "," + String(buffer0); writeSD(logEntry); Serial.println(logEntry); } } } for (throttle = 180; throttle >= 0; throttle -= increment) { for (int x = 0; x < readings; x++) { if (STOP) { esc.write(HALT); // Shut down Motor NOW! Serial.println("Halting Motor"); } else { wait (pause); esc.write(throttle); // increment the ESC wait (200); ESC = throttle * 100 / 180; getData(buffer0); wait (100); getData(buffer1); String logEntry = String(ESC) + "," + String(buffer1) + "," + String(buffer0); writeSD(logEntry); Serial.println(logEntry); } } } Serial.println("End of Test Pass"); wait (testDelay); } esc.write(HALT); // Shut down Motor NOW! } } void writeSD(String logdata) { File logFile = SD.open("NANO_LOG.csv", FILE_WRITE); if (logFile) { logFile.println(logdata); logFile.close(); } else { Serial.println("Error writing log data"); } } void wait(unsigned long i) { unsigned long time = millis() + i; while(millis()<time) { } } void start_ISR() { START = 1; STOP = 0; } void stop_ISR() { STOP = 1; START = 0; } void getData(char* buff) { Wire.requestFrom(9, 32); for (byte i = 0; i < 32 && Wire.available(); ++i) { buff[i] = Wire.read(); if (buff[i] == '#') { buff[i] = '\0'; break; } } } This is the SD card contents: % Thr,Thrust,Curr,Volts,RPM,Cell1,Cell2,Cell3,Cell4,Cell5,Cell6 0,-12,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 0,-12,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 0,128,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 This is the output from the serial monitor: Thrust Meter I2C Master Card Ready % Thr,Thrust,Curr,Volts,RPM,Cell1,Cell2,Cell3,Cell4,Cell5,Cell6 Start Pressed 0,-12,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 0,-12,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 0,128,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 25,2062,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 25,2520,0.00,15.75,0,3.10,4.20,3.96,3.96,0.00,0.00 25,2710,0.00,15.75,0,3.10,4.20,3.96,3.96,0.00,0.00 50,519,0.00,15.75,0,3.10,4.20,3.96,3.96,0.00,0.00 50,216,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 50,2288,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 75,890,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 75,891,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 75,1386,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 100,2621,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 100,2424,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 100,692,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 100,3409,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 100,227,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 100,3349,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 75,2220,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 75,2249,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 75,509,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 50,1977,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 50,2986,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 50,546,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 25,3746,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 25,3337,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 25,3015,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 0,96,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 0,-12,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 0,-14,0.00,15.76,0,3.10,4.20,3.96,3.96,0.00,0.00 End of Test Pass
The solution to the problem was to replace the SD card with a faster one. Once I did that the data logged as it should. Thanks Patrick for the suggestion.
Light flashes more times than it's asked to
I am trying to get my LED to flash when the hypotenuse enters certain range. But it seems like it's passing that value of hypotenuse range more times than it should. LED Flashes for about good 30 -40 times before it goes back to being normal. Not sure how to fix this problem. This is my processing code: import processing.serial.*; float r_height; // rise of the slope float r_width; // run of the slope float hypotnuse; // hypotenuse of the right angle int d = 20; // diameter of the chocolate float x ; // x of the chocolate destination float y ; // y of the chocolate destination int ledGlow; // how much the LED will glow Serial myPort; // serial port object void setup () { size (510, 510); // size of the canvas String portName = Serial.list()[8]; // my arduino port myPort = new Serial(this, portName, 9600); background (0); // color of the background fill(204); // fill of the ellipse ellipseMode (CORNER); //Ellipse mode x = 0; //The placement on initial X for chocolate y = 0; // the placement on initial Y for chocolate ellipse (x, y, d, d); // ellipse frameRate (30); } void draw () { r_height = mouseY - y; // rise r_width = mouseX - x; //run hypotnuse = sqrt (( (sq(r_height)) + (sq (r_width)))); //A^2 +B^2 = C^2 ledGlow = 255 - (round (hypotnuse/2.84)); // flipping the values myPort.write(ledGlow); // The value being sent to the Arduino println (ledGlow); } This is the arduino code: float val; // Data received from the serial port int ledPin = 9; void setup() { pinMode(ledPin, OUTPUT); // Set pin as OUTPUT Serial.begin(9600); // Start serial communication at 9600 bps } void loop() { if (Serial.available()) { // If data is available to read, val = Serial.read(); // read it and store it in val // long steps2move = val.toInt(); } if (val > 230) { analogWrite (ledPin, 255) ; // I have already tried digitalWrite delay (100); analogWrite (ledPin, 1) ; delay (100); } else if (val < 230) { analogWrite(ledPin, val); } } UPDATED ARDUINO: float val; // Data received from the serial port int ledPin = 9; // Set the pin to digital I/O 13 unsigned long currentTime = 0; unsigned long pastTime = 0; int currentState = 0; int wait = 0; void setup() { pinMode(ledPin, OUTPUT); // Set pin as OUTPUT Serial.begin(9600); // Start serial communication at 9600 bps } void loop() { if (Serial.available()) { // If data is available to read, val = Serial.read(); // read it and store it in val // long steps2move = val.toInt(); } if (val > 230) { pastTime = currentTime; currentTime = millis(); unsigned long timePassed = currentTime - pastTime; if(timePassed >= wait) { switch(currentState ) { case 0: digitalWrite(9, HIGH); wait = 500; currentState = 1; break; case 1: digitalWrite(9, LOW); wait = 500; currentState = 0; break; } } } else if (val < 230) { analogWrite(ledPin, val/2); } }
The processing code is presumably writing out to serial constantly. However, when the hypotenuse enters the range you've set, the Arduino has those delay() calls. I think that will be causing it to lag behind, so it keeps flashing while it clears the backlog of serial data that came in during the delays. I think a better approach is to avoid using delay() at all, so the Arduino can handle the serial data as fast as possible. On each loop, it should first grab the latest serial data (if there is any). Based on that, it should figure out and store what the LED should currently be doing (i.e. whether it should be flashing, or else what brightness it should be). After that (regardless of whether any serial data was actually received), the LED can be updated from the stored state. Remember not to use delay() for the flashing though. Instead, you could keep track of the last time it flashed on, and figure out if 100 ms has passed since then (using millis()). If so, switch it off. If another 100 ms has passed, switch it back on. This approach decouples the flash timing from the serial data, so hopefully it should work better.