Hacker Newsnew | past | comments | ask | show | jobs | submit | Ives's commentslogin

Second to last point:

> While some recommendations include using a paper towel to turn off the faucet after hands have been rinsed, this practice leads to increased use of water and paper towels, and there are no studies to show that it improves health.


Thanks. I guess depending on the faucet you could use your elbow.


I really don't like I2C. Yes, in principle it's pretty simple, but if you consider NACKS, slaves holding SCK low, what happens if your master resets while the slave is trying to send a 0 bit (hint: power cycle!), etc, it's so easy for the peripheral to get stuck.

SPI is much easier to write correctly, and pretty much only has the extra wire (usually not a problem) and the phase polarity issues as a negative point.


Same. I really dislike I2C, but it's universal and it's been around for decades, and it's hard to avoid designs without it. I2C keeps causing these additional issues which the article doesn't touch on:

* No way to safely bring the bus back to idle from mid-transaction. By "safely" I mean not accidentally transmit an extra byte which could e.g overwrite EEPROM memory. There is no combination of transitioning the 2-wire bus from an arbitrary state back to idle which works in the general case. If it's important, you end up adding a dedicated reset wire.

* No safe, universal way to bring the bus from tristate, or low, to pulled-up. There are designs where this ends up being necessary. You end up with a spurious transaction, which may wedge the bus, or having to add a reset wire or buffer.

* The protocol is extremely hostile to devices with non-zero latency response. It's designed as a simple "Address this register and then immediately read out a byte in the next clock cycle". Works great for trivial devices, but for anything more complex it ends up needing a bank of register acting as a "proxy" to access the higher latency side of the chip. At this point I2C is an awesomely bad choice, but people keep doing this, because it's so universal.


> No way to safely bring the bus back to idle from mid-transaction. [...] No safe, universal way to bring the bus from tristate, or low, to pulled-up.

These are great points, and I'll add a note about them in the article. Thanks!

> The protocol is extremely hostile to devices with non-zero latency response. [...]

Technically, this is what clock-stretching is for. In practice, you're right that complex devices implemented proxy registers. I've seen it on DP->MIPI bridges for example.


There is a safe, out of band way to do this that system designers can utilize. Reset all the other peripherals on the bus.


Wow


> No way to safely bring the bus back to idle from mid-transaction.

Why would you want to do that? Not having the ability to do this is part of the contract. If you design your device such that it always completes the transaction, then there should be no problem, unless one of the devices on the bus doesn't play fair but then you have a different problem.


Say you’ve asked an I2C ROM for a block read. After the first byte something, also on the bus, asserts an interrupt via a side band GPIO. I can’t read the something until the block read finishes.


The specific case I was thinking of was the host suffering an incident where it is not possible or practical for its software to know where it left off.

For example, you get a kernel panic, or soft-reset for some reason. When you recover, you now have a bus in an unknown state, possibly mid-transaction, and if you pick the wrong order in which to bring the bus back to idle, you might wedge it or accidentally cause a side-effect (e.g overwrite a byte in an EEPROM).


But doing bus communication from software is generally a bad idea. Best is to use a hardware controller dedicated to the task. Do you have examples for bus protocols that can be run from software?


I assert NACK, and the block read terminates. Then I service the interrupt.


I built a battery powered project designed to run continuously for ten years. Of all the things in that design, the I2C bus makes me the most nervous (1). Every time the MCU wakes up it has to use I2C to read from the RTC. If at any point in that ten year span the I2C bus gets jammed ...

I mitigated the issues by doing I2C resets on every read (see the Analog Devices I2C reset documentation linked in another comment) and reading multiple times to filter out any spurious bit errors.

Other than that I just have my fingers crossed that a bit doesn't accidentally flip and overwrite something in the RTC. Or that the bus somehow gets stuck driven between sleeps and drains the battery early. sigh SPI would have been so much nicer.

(1) I mean, okay, the massive lithium battery exploding is perhaps the most nerve racking component, but I2C is a close second.


I think I2C and SPI have very different use cases. Over I2C, you can interact with 127 devices with just 2 pins. To do the same with SPI, you'd need 130 (4 + an additional CS for every device on the bus).

You may think of the extra pins as not a problem, but on every product I've worked on we've been pin-limited on the MCU.


> Over I2C, you can interact with 127 devices with just 2 pins.

In practice, I don't see that many chips offering 7 bits of address configuration. You buy a chip, it has a hardwired address. Maybe a pin or two for selecting another address.


There was the design I did quite a few years ago now. Grabbed a old design, changed the board shape, put a third I2C device on. Everything powered up beautifully first go... and it was only then we worked out two of the devices from different vendors had the same I2C address. <facepalm>


That's still seven bits of address, though. If you're lucky, the hardwired part will be different enough between chips that you can still have a significant number of them on a bus.


I've yet to get above 4 devices without conflicts. Even with evenly distributed addresses, you reach about 50% chance of conflict with 13 devices because of the birthday paradox.


Agreed, but most I2C busses only have 2 or 3 devices on them. There are some boards with 16 or so devices on the same bus, but much more than that and you'd better hope you can either program their addresses or order them with a specific address, or you might end up with 2 chips with the same address.


I've worked on server hardware with dozens of devices on a bus :-). Making sure addresses were programmable was a must indeed.


This happened to me once. Used proximity infrared sensors that used I2C with a fixed address. Needed to use multiple of them. I was able to fix it with a tri-state buffer, but quite the pain to figure out why things were not working and coming up with a solution.


For that many devices on SPI, run 7 pins to an address decoder that fans out to 128. You can do this in the spare pins of an FPGA that you might have for some other purpose, and the 7 pins are cut down to one or less if you've already put much into the FPGA. For example, the FPGA provides 4096 bytes of registers (12 address bits) to the MCU but only needs 3700 registers, so use one of the spare bytes to control which SPI CS is enabled.

I've also seen JTAG as an alternative to I2C and SPI. JTAG can be part of normal operation.


Not always the case that you need the pin count, a good number of SPI devices support daisy chaining[1].

[1] https://www.maximintegrated.com/en/design/technical-document...


Cool! I've never seen this before.


The downside is of course that you need a lot of clock cycles before the data reaches the corresponding device, which makes this too inefficient for certain applications.


If you only want to select one device at a time (which is often the case) then you only need log2(devices) pins on the microcontroller because you can decode that binary number into the appropriate chip select.

Obviously that requires more hardware on the board tho'.


I don't think I've ever run more than 5 or 6 devices on an I2C bus without running into rise time, bus contention, or address collision issues. Some devices scoop tons of addresses, and most only allow re-assignment to a few alternate addresses.

I agree it's still lower pin count than SPI, but realistically you don't get anywhere near 127 devices.


this is a very good point, and i have had the same experience. its also super common for very cheap, very low end custom ics to use i2c for the same reason; keeping the pin count and package size down


Don't forget the reset lines to each device that you need to release the bus when they get locked up!


No reason why you need to reset them individually ;-).


For exactly that reason, I've encountered peripherals getting stuck during i2c transactions far too many times. At least a handful of times I've had to add boot (and sometimes runtime) logic to clear stuck transactions, due to the lack of a dedicated way to reset said peripheral.

It's quite annoying because one stuck device can block all other communication on the bus. Let's hope your reset pin (if you have it), isn't on an i2c expander on the same i2c bus.


For what it's worth, here is a good doc on I2C resets: https://www.analog.com/media/en/technical-documentation/appl...


> SPI is much easier to write correctly

I'm not sure that I buy that. A daisy chained SPI bus is a rats nest of configuration hassle and basically impossible to debug. You're trading hardware robustness for software complexity, and that's not always a win.

And as far as hardware messes: SPI doesn't synchronize anything beyond the bit level (modulo an out of band chip enable or reset, of course, which would work to "fix" an I2C device too), making shift/offset bugs a real danger.

Board-level digital interfacing is just hard. That's why we do it as little as possible and put everything on the SoC these days.


There are so many buggy I2C devices out there, I wouldn't say you're gaining hardware robustness, either.


I2C has caused me probably the most grief out of all the buses, as it's been the most painful to work with when designing the schematic (because even with only 3 devices you have to deal with address conflicts), initially writing the software (because the specification is quite lax on what can happen when, inevitably the interface between hardware and software is quite complex and a lot of it is very latency sensitive. A lot of hardware for it is quite buggy or just poorly designed as well), and in terms of ongoing bugs and issues (because of said latency sensitivity and propensity for locking up).

I try to avoid it as much as possible. If I need a peripheral, I prefer SPI, if I need a bus for connecting devices I control, I use CAN. If I'm connecting two systems together, a UART.


This sounds much like a brown-out where only half the system resets or worse, parts of it go into an undefined state. The proper way to deal with this is a complete reset/power cycle.

Granted, that's not easy to do if your peripherals have no reset pin or their power source cannot be switched by the bus master.

Would your problems go away if you had I2C plus a dedicated reset pin on all peripherals?


SMBus (which is close enough to call I2C) is also a major pain in the ass for Linux integration. If a master goes out of sync with a slave, or a poorly programmer slave tries to multi-master the bus or something, your kernel will hang and crash.


On the other hand you need a lot more pins for SPI.

One more advantage of SPI that I see is higher data rates, full-duplex communication etc..


An important part:

> This is an observational study, and as such, can’t establish cause. And the researchers caution that the number of included studies was small and their methods varied considerably, which may have influenced the results.

People who are sick or have other health issues will do very little running, so correlation and causation and all that.


Similar to how a low BMI has higher death rates than overweight BMI IIRC. People tend to lose a lot of weight when they are really sick.


You can still use the Uint32/Uint8/... types. While performance can vary from system to system, the range should be the same on all reasonable platforms.


Not really, the C++ macro provides information about which source file the statement was generated from, as well as color coding.


  1> (defmacro dbg (expr)
       (with-gensyms (val)
         ^(let ((,val ,expr))
            (format t "~a: ~s -> ~s\n" (source-loc-str ',expr) ',expr ,val)
            ,val)))
  dbg
  2> (dbg (cons 1 2))
  expr-2:1: (cons 1 2) -> (1 . 2)
  (1 . 2)
  3> (dbg (+ 2 2))
  expr-3:1: (+ 2 2) -> 4
  4
  4> (progn
       (dbg (list 1 2))
       (dbg (cons 1 2))
       (dbg (+ 1 2)))
  expr-4:2: (list 1 2) -> (1 2)
  expr-4:3: (cons 1 2) -> (1 . 2)
  expr-4:4: (+ 1 2) -> 3
  3
Colorization is just inserting some trivial ANSI codes. Arguably, this just slows down the program even more and increases the size of the log files. It can be done as a post-processing filter.


Not all of the Greek letters seem to be in the database: a search for "Psi" doesn't reveal ... \psi ...


Thanks! Adding them right now!


...and done! :)


Epsilon is also missing.


I wonder when we can start using this function without running the risk that our bosses/clients Excel doesn't support this function. Lots of people still use Office 2007 and 2010, so It'll be a while I guess.


I wonder if this function can be emulated on older versions of Excel.


I was thinking about that too. Although any form of delivering automatically executing code is just another attack vector. It's macro's all over again.


The details of this also vary based on where you're at. In the US, neutral is bonded to earth at every house I think. In Europe, neutral is only bonded to earth at a local power station.


The US system is somewhat unique and lacks heaps of safety features: I am guessing mostly because a 110V shock is far less dangerous than a 240V shock (Although higher amperages mean higher risk of fire?).

For example for UK, EU and NZ etc: sockets and pins have a variety of features to avoid touching the phase (live) wire with say a screwdriver or knife in hands of a child.

For example, all new circuits installed in New Zealand since 209 must have an Residual Current Detector (the actual rules lead to multiple RCDs per main power board). This will cut the circuit if someone does manage to touch a live wire somehow (current from phase to neutral doesn't match, because some of it is grounded through your body, and the mismatch triggers the breaker. Wayyyyyyy safer than a fuse!


In the US there is tamper proof outlets and GFCI is equivalent to RCD. Its pretty much required for new houses though older houses may vary on what they implement.


Are tamper proof outlets mandatory? The UK has had shutters on the phase that is opened by the earth pin forever. Which is why their plugs are caltrops, and have a plastic earth pin if double insulated (only phase and neutral wired, with no earth wire).

I don't think I have ever seen a US plug where the pins have a non-conductive protective covering at the base of the pin (I think all modern UK and NZ male plugs have that. Although I'll be honest that I think the NZ solution makes plugs less safe due to risk of pins bending then breaking and leaving a live metal pin exposed in the socket).

EU sockets are mostly recessed from what I have seen (some NZ sockets are, but the recess is still is often unusable with old plugs, so is not common yet, but will become so as more plugs are sold that fit properly).


> The UK has had shutters on the phase that is opened by the earth pin forever. Which is why their plugs are caltrops

No, bad design is why they are caltrops. Over here in the Netherlands shutters are similarly required but none of our plugs need a third pin. The shutter is a see-saw construction that works in such a way that you need to insert both prongs at the same time for the shutter to rotate out of the way.

That said our grounded plugs are still caltrops for no real good reason, though less so than the UK ones. They tend to fall with the prongs to the side instead of prongs-up.


> Are tamper proof outlets mandatory?

Its required by current US NEC code but older house are grandfathered in unless they do major renovation. Also some exceptions like outlets high enough to be out of reach of kids.

Its possible that the UK/NZ plugs have better designs. The code improves step by step here.


Yeah, this is 100% based on the US electrical system. I am not familiar enough with how other countries do it to speak intelligently on their systems.


Not quite, there are different systems in service depending on region and installation era: https://diy.stackexchange.com/questions/134392/in-germany-sh...


Electricity is still cheaper than gas, but electricity in many European countries these days is at least 30 cents per kWh (and rising every year), instead of the 15 cents you mention.


The eMPG is an attempt to convert WH/m into MPG based on some fixed numbers for $/kWh and $/gallon.

a WH/m x b $/kWh / 1000 = x $/mi

c $/ga gasoline / x $/mi = mpg equivalent.

For a=300, b=0.15, c=$3.00 you get 66mpg.

You can plug in your own numbers as you see fit.

The cost savings is then estimated by plugging in a number of miles driven, and comparing gallons of gas versus a hypothetically less efficient car (not sure what MPG rating Tesla uses for its comparison)

Note that the Tesla Model 3 is closer to 150 WH/mi. And what does gasoline cost in those European countries?


€1.3 per litre, so that's $5.53 per gallon.


How about the fact that a software developer in Silicon Valley earns much more, up to twice as much as one in London? Before taxes that is.


I would be more interested in after taxes earnings and things like holidays, healthcare and so on. Also you are most likely not able to get your family to the US to visit you. This is a huge downer I can imagine for a lot of people.


As a general indication, the average software developer in the UK earns about 45k$, while the average in the US is more like 60k$ (source: payscale). The averages for London and Silicon Valley will both be higher than that of course.

Healthcare insurance is more expensive in the US, but this is compensated by much lower taxes.

You're definitely right about holidays and vacation days, you'll have more of these in the UK. At the same time, even when you value a vacation day at 300$ (much more than either average UK or US dev earns in a day) and suppose our average UK dev has 20 more vacation days a year (he probably doesn't), that's still only 6k out of a 15k difference.

I agree that being near your family and friends can be worth a lot more than 15k$.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: