Is it possible to use 2 teensy 3.5's together for I2C?

Status
Not open for further replies.

uuryuu

Member
Hello,

I was wondering if its possible to have 2 teensy 3.5's hooked up together, where one teensy is a master and another teensy is a slave using I2C?Having trouble looking this up....l

Thanks
 
Yes for WIRE.h usage there are MASTER and SLAVE examples that should work see : {local install}\hardware\teensy\avr\libraries\Wire\examples

Also same for i2c_t3.h that works on T_3.x:: {local install}\hardware\teensy\avr\libraries\i2c_t3\examples
 
Thank you,this is very helpful. I didn't know about i2c.t3.h!
But I wanna try and get 2 teensy's to begin recording an analog channel respectively on the minute, for a small duration(10 seconds) at the sametime,so they have same timestamp.Using timelib.h.

So:
Teensy1 starts recording from its own A3 @ 13:00:00 -> fills a 10sec buffer -> then waits till 13:01:00 to start again
Teensy2 starts recording from its own A3 @ 13:00:00 -> fills a 10sec buffer -> then waits till 13:01:00 to start again

I know there's gunna be a delay between slave requesting time from master->master sends time->slave saves time..But wanna see if its negliable...If you know of better way,I'm all ears.
 
Add a digital line I/O line that the I2C controller ("master") can pulse and the I2C responder ("slave") can read.
1. The I2C controller pulses the digital line using digital write fast at the time that you would like sync'd.
2. An interrupt in the I2C responder grabs its time at the pulse
3. The I2C controller sends the responder the time that the pulse occurred at.
4. The I2C responder can compute the time offset from the time stored in the interrupt. Applying the offset is a simple approach to synchronizing the clocks.
 
I think I got what you mean. Heres a rough thought process

(master)
-pulse(toggle) digital pin fast when time to sync
-save the current time of pulse


(slave)
-setup isr to monitor digitalpin
-turn on isr before we need to sync (I don't like idea of the isr constantly being called and watching pin while recording adc)
-if isr digitalpin== high, grab slaves current time
-request masters time ,which is start of pulse
-calculate offset, set slaves time according to offset

isr()
-if digitalpin read fast ==high -> flip a bool to notify syncing is starting

So if:
-after requesting a sync
-master time equals 13:00:50
-slave time = 13:00:52
-offset = 2 sec
-set: slave time = slave time - offset

Something like this? If I understand correctly
 
I think I got what you mean. Heres a rough thought process

(master)
-pulse(toggle) digital pin fast when time to sync
-save the current time of pulse


(slave)
-setup isr to monitor digitalpin
-turn on isr before we need to sync (I don't like idea of the isr constantly being called and watching pin while recording adc)
-if isr digitalpin== high, grab slaves current time
-request masters time ,which is start of pulse
-calculate offset, set slaves time according to offset

isr()
-if digitalpin read fast ==high -> flip a bool to notify syncing is starting

So if:
-after requesting a sync
-master time equals 13:00:50
-slave time = 13:00:52
-offset = 2 sec
-set: slave time = slave time - offset

Something like this? If I understand correctly

Close.

1. For the ISR, you don't have to check the pin state, you can just attach the ISR on the leading edge of the pulse, assuming that it's a positive pulse (i.e. low to high), check for the rising edge:

Code:
int my_time;

void SetTime() {
  my_time = micros();
}

void setup() {
  attachInterrupt(isr_pin, SetTime, RISING); 
}

This isn't polling, the ISR isn't constantly being called. It's only called when the pin is pulsed.

2. Don't have the responder/slave ask for the time from controller/master. Have the controller/master just send it after the pulse. The controller/master can send data to the responder/slave in I2C without the responder/slave requesting it. It will cut down on bus traffic and is the flow of information that I would expect, since the controller/master is in control of the bus.

3. You decide when to do the time sync. If all of your data collection occurs at the top of a minute, have the time sync occur at the 30 second mark.

Alternatively, you might ask why you are even trying to time sync. You could just use a digital line from the controller/master to synchronize the data collection and the responder/slave doesn't need to keep track of time at all. From the responder/slave stand point, the code would look like:

Code:
volatile bool collect_data = false;

void Daq() {
  collect_data = true;
}

void setup() {
  attachInterrupt(sync_pin, Daq, RISING);
}

void loop() {
  if (collect_data) {
    /* Reset the flag */
    collect_data = false;
    /* Do the analog read, etc */
  }
}
 
I like this idea alot, why bother having both teensy track time and try to sync. Just wait till digitalpin pulses and collect data on slave,only thing that also needs to be sent is time from master,so they have same timestamp..But thanks! ill give it a go this weekend when I have time, but this sounds like easiest way to go about it.
 
Hrm....I think, just request the time when pulse occurred after recording, this way both teensys record at nearly same time, and after this ,take my time to ask Master for time when pulse happened.
 
Last edited:
Hrm....I think, just request the time when pulse occurred after recording, this way both teensys record at nearly same time, and after this ,take my time to ask Master for time when pulse happened.

Is i2c already part of the connected T_3.5's?

If not - are they in close proximity where UART Serial# would work? UART Serial# ports can run at higher speed if just communicating between these two devices. Also I found that an interrupt could be triggered by the Rx Line dropping LOW at the start of a transmission when the Start bits take the line form HIGH after prior Stop bits. So connecting with GND and Rx and Tx the baud rate could be selected for the wires in use to be reliable.

If the only reason the Master sends a message is to start sampling: On interrupt of Rx pin, take timestamp locally for the record, disable the interrupt, start sampling and read the Master message after it arrives while collecting data. When data collection, or Master message is done, re-enable the interrupt. Or if other things come form Master - have the Master send a message "Ready for collection" - the Master could then pause for the message to transmit to allow the 'Stop' condition of the UART to establish, enable the interrupt and respond at that point as above.
 
By part of , do you mean physically connecting I2C to both teensy 3.5's? If so yes,for now, but I can't seem to get i2c_t3.h to run basic master/slave example properly.Master sends data but slave never receives,and both have external pullup resistors 4.7k,I've tried 2k-5.5k, I think I might start a new thread for this,if can't get it going after further testing.Same issue with wire.h....im overlooking something.


But I do like having options such as UART,this sounds doable as well. Ill have to test and play around for abit,but thank you all for more then one way to solve it. I couldn't of asked for better peeps to reply.
 
Last edited:
By part of , do you mean physically connecting I2C to both teensy 3.5's? If so yes,for now, but I can't seem to get i2c_t3.h to run basic master/slave example properly.Master sends data but slave never receives,and both have external pullup resistors 4.7k,I've tried 2k-5.5k, I think I might start a new thread for this,if can't get it going after further testing.Same issue with wire.h....im overlooking something.


But I do like having options such as UART,this sounds doable as well. Ill have to test and play around for abit,but thank you all for more then one way to solve it. I couldn't of asked for better peeps to reply.

By 'Part of' I was wondering if there are other i2c devices in use? Or was i2c just chosen as a way to connect them, and not used with any other devices on i2c bus?

If the i2c was just put into use to connect them - and they are close enough for reliable wiring for UART signals - side by side or a few inches - that I'd use UART Serial. It should run at 1 or 2 Mbaud.
 
I see what you mean now, apologies. And yes there is a I2C device a DS3231 RTC hooked up to master(although, I might buy another and hook up to slave). And master has 2 functions: 1) tell slave to begin recording. 2) send current timestamp of RTC on master to slave

But I was able to use UART successfully to send/receive on interuppt and begin recording, which is great! I took a break from i2c_t3.h lib, and got UART to work.

Time it takes to:
Send time from master to slave = 1 micro second
Receive and store time from master = 16 micro second

Which is perfect and well within my range for accuracy.


But I then decided to try adding SD cards into the mix for both Teensy's,and I am having a head scratcher on how to sync them so they have same timestamp up to millisecond,if this is even possible.......

When testing the time it takes to create a file for master or slave ,it varies between 2400-3500 micro seconds.I know creating and writing times to SD can vary, from SD card to SD card,and how they prefer 512 bytes block. But I wanted to see if I can sync them so they have close to same timestamp up to millisecond, while only using 1 RTC on master.

As example from testing:
(year:month:day:hour:minute:second:millisecond)
Master time Filename: 2021:01:01:00:00:00:500.bin
Slave time Filename: 2021:01:01:00:00:00:850.bin

I'll sit and think on it more,need a break. But at least I got UART working like I wanted it to lol. Any ideas are greatly appreciated.
 
Status
Not open for further replies.
Back
Top