element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Just Encase
  • Challenges & Projects
  • Design Challenges
  • Just Encase
  • More
  • Cancel
Just Encase
Blog Blog 10 - Bringing the hardware all together - Part 2 [updated]
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Just Encase to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: christophesky
  • Date Created: 26 Feb 2022 11:46 AM Date Created
  • Views 2188 views
  • Likes 13 likes
  • Comments 7 comments
  • Arduino MKR WAN 1300
  • garden pond monitor
  • remote monitoring
  • just_encase
Related
Recommended

Blog 10 - Bringing the hardware all together - Part 2 [updated]

christophesky
christophesky
26 Feb 2022
Blog 10 - Bringing the hardware all together - Part 2 [updated]

After a little break in the new year and the full force of back to work I have finally had some time to set about documenting part 2 of my build.

The blog so far:

Links should open new tabs / windows

Sections 1-4. Initial thoughts, requirements,excitement and unboxing.

  • Blog 1 - The what and why (Garden pond monitoring Background and Introductions)
  • Blog 2 - My Method or WWHW (What, Why, How, When)
  • Blog 3 - excited as its on the way
  • Blog 4 - Arrivals, Unboxing, Github and requirements

Sections 5 - 9, design build, code and test, so much testing

  • Blog 5 - Getting started with the MKR 1300 (and LoRa Sender Starting LoRa failed!)
  • Blog 6 - The Soak Test UPDATE 2 (Test 3 - sump pump and soak)
  • Blog 7 - Sensors, connections and starting some code - draft / wip
  • Blog 8 - Measure, send, receive, transform, store, display (updated with code)
  • Blog 9 - Bringing the hardware all together - Part 1 (updated)

This is Blog 10,  part 2 of the build progress as the final step before going live and outside.

Blog 11, will be about commissioning and then collecting real world data

The final blog number 12 will wrap up and cover the following:

  • Original functional and non functional specifications - mapped to what was done and tested.
  • Orignal design vs final design - retrospective on the good, the bad, the confused.
  • What could have been done better and lesson learnt.
  • Data to insight - now I am measuring what can I do with that information
  • Final bill of materials, for all parts, extras and bits used, for both hardware and software
  • and finally, a single PDF of the whole build so someone else could replicate

Platform Build

My original plan was for the Hammond Enclosure to have a bracket and be pole mounted to the back of the pond edge, this has now not proven possible with the length of some of the sensors I am using as this would limit me only to the margins of the water, these are shallower tend to get warmer and have readily available dog access (a risk). Looking into alternatives such as locating the main Hammond Enclosure closer to the waters edge were also ruled out, pretty much for the same reasons, with the addition of secure mounting then becoming an issue.

I decided on a more radical approach which is to put the main Hammond Enclosure ontop of the pond, positioned above the deepest part (c.1m), but how shall you do this I hear you say!

Let me introduce you to Floaty McTest Face

Floaty McTest Face

4No 92.5 degree bends.

4No 150mm lengths of 110mm of underground drainage pipe

8No rubber gaskets and c.300ml of marine / aquatic life safe, submersable sealant

image

I had made a video of me starting to assemble this, whcih is fine until you get to the part where 92.5 degrees becomes a problem. So after lots of red faced pipe wrestling, reseating of gaskets and to be honest, brute force, I have my floating platform. Given this was also the source of first blood on the project, it felt only appropriate to christen my creation, Floaty McTest Face was born.

image

I have designed and 3d printed brackets and supports to add a assembly frame mounted on the floating platform. This uses 1515 alu profiles, 90 degree corner joints and then some fixtures and fittings of my own creation. STLs and the design files will be loaded into the github and shared. Printed in ABS and a very snug fit, with tiny tiny tiny tolerances, this was the source of second blood being drawn, which serves to only reaffirm prior to the main launch, a naming was indeed appropriate. (I am a simple man and easily amused, however the end of a 1514 alu profile with force across the side of your hand does indeed leave a bit of a mess and likely scar, this shall be known as E14 Ham from hereon in)

ON the central two vertical profiles I will be mounting the Hammond Enclosure, using the through the frame mounting holes accessed with the enclosure lid off, these will be secured into the 1515 alu profile by 4 short bolts into friction slides (and will not move once installed).

To the front of the assembly and again for the rear of the assembly we shall have

  1. pH probe
  2. Water temp sensors 1 & 2
  3. TDS probe
  4. Turbidity probe

I have designed in a replaceable mount (clip and lock) to enable to me to later add a ORP probe as well, once I can find some in stock / reasonably priced).

The side of the 1515 alu frame will also house my weather shield which containts the light level sensor and a BME280. So this means I have tested all that I intended to test in the pond and have the ability to add more as I go)

Software and Device Build

Software so Far

Its not the most elegant, but it works :)

//Libraries

#include <SPI.h>
#include <LoRa.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "DHT.h"
#include <DHT_U.h>
#include <math.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DFRobot_B_LUX_V30B.h>

//Constants

//LUX meter
DFRobot_B_LUX_V30B    myLux(13,5,6);

//pH Sensor
#define pHSensorPin 0
#define VREF 5.0
#define SCOUNT 30

//Turbidity Sensor
#define TurbSensorPin A1

//TDS Sensor
#define TdsSensorPin 3

//DHT22 pin and object name
DHT dht(2, DHT22);    // Initialize DHT
//#define DHTPIN 2
//#define DHTTYPE    DHT22     // DHT 22 (AM2302)


//One Wire Bus (temp sensors - water)
#define ONE_WIRE_BUS 0

//Variables

int counter = 0;

// one wire
// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);

int deviceCount = 0;
float tempCu;
float tempCl;

//TDS Meter
int analogBuffer[SCOUNT];    // store the analog value in the array, read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0,copyIndex = 0;
float averageVoltage = 0,tdsValue = 0,temperature = tempCl;

//pH sensor
unsigned long int avgValue;  //Store the average value of the sensor feedback
float phValue=(((phValue=(float)avgValue*5.0/1024/6)*3.5));
float b;
int buf[10],temp;

//BME280
Adafruit_BME280 bme;

//dht22
int chk;
float enc_humidity;  //Stores humidity value
float enc_temp; //Stores temperature value

//lightiness (open enclosure)
float lightsensor; //Resistance of grove light sensor (v1.2) in K

//turbidity
int sensorValue = analogRead(TurbSensorPin);
float turbidity = sensorValue * (5.0 / 1024.0);

///////////////////////////////////ends/////////////////////////////////

void setup() {
  Serial.begin(9600);
  sensors.begin();
  sensors.setResolution(9);
  dht.begin();
  myLux.begin();  
 
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
 
  LoRa.begin(868E6);
}

void loop() {
  int sensorValue = analogRead(TurbSensorPin);
  float turbidity = sensorValue * (5.0 / 1024.0);
  gettds();
  getph();
  getlight();
  gettemp();
  Serial.print(bme.readTemperature());
  Serial.print(",");
  Serial.print(bme.readPressure() / 100.0F);
  Serial.print(",");
  Serial.print(bme.readHumidity());
  Serial.print(",");
  Serial.print(tdsValue);
  Serial.print(",");
  Serial.print(phValue);
  Serial.print(",");
  Serial.print(dht.readHumidity());
  Serial.print(",");
  Serial.print(dht.readTemperature());
  Serial.print(",");
  Serial.print(lightsensor,DEC);
  Serial.print(",");
  Serial.print(sensors.getTempCByIndex(0));
  Serial.print(",");
  Serial.print(sensors.getTempCByIndex(1));
  Serial.print(",");
  Serial.print(turbidity);
  Serial.print(",");
  Serial.print(myLux.lightStrengthLux());
  Serial.print(",");
  Serial.print("Sending packet: ");
  Serial.println(counter);
  LoRa.beginPacket();
  LoRa.print(bme.readTemperature());
  LoRa.print(",");
  LoRa.print(bme.readPressure() / 100.0F);
  LoRa.print(",");
  LoRa.print(bme.readHumidity());
  LoRa.print(",");
  LoRa.print(tdsValue);
  LoRa.print(",");
  LoRa.print(phValue);
  LoRa.print(",");
  LoRa.print(dht.readHumidity());
  LoRa.print(",");
  LoRa.print(dht.readTemperature());
  LoRa.print(",");
  LoRa.print(lightsensor,DEC);
  LoRa.print(",");
  LoRa.print(sensors.getTempCByIndex(0));
  LoRa.print(",");
  LoRa.print(sensors.getTempCByIndex(1));
  LoRa.print(",");
  LoRa.print(turbidity);
  LoRa.print(",");
  LoRa.print(myLux.lightStrengthLux());
  LoRa.print(","); //included at end of main data string as RSSI is added last
  LoRa.endPacket();

  counter++;
  delay(30000);
}

/////////////////////////////////////////////////
////////Function things TDS, pH, Light///////////
/////////////////////////////////////////////////


void gettemp()
{
  // Send command to all the sensors for temperature conversion
  sensors.requestTemperatures();   
  tempCl = sensors.getTempCByIndex(0);
  tempCu = sensors.getTempCByIndex(1);
}

void gettds()
{
   static unsigned long analogSampleTimepoint = millis();
   if(millis()-analogSampleTimepoint > 40U)     //every 40 milliseconds,read the analog value from the ADC
   {
     analogSampleTimepoint = millis();
     analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer
     analogBufferIndex++;
     if(analogBufferIndex == SCOUNT)
         analogBufferIndex = 0;
   }   
   static unsigned long printTimepoint = millis();
   if(millis()-printTimepoint > 800U)
   {
      printTimepoint = millis();
      for(copyIndex=0;copyIndex<SCOUNT;copyIndex++)
        analogBufferTemp[copyIndex]= analogBuffer[copyIndex];
      averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value
      float compensationCoefficient=1.0+0.02*(temperature-25.0);    //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
      float compensationVolatge=averageVoltage/compensationCoefficient;  //temperature compensation
      tdsValue=(133.42*compensationVolatge*compensationVolatge*compensationVolatge - 255.86*compensationVolatge*compensationVolatge + 857.39*compensationVolatge)*0.5; //convert voltage value to tds value
   }
}
int getMedianNum(int bArray[], int iFilterLen)
{
      int bTab[iFilterLen];
      for (byte i = 0; i<iFilterLen; i++)
      bTab[i] = bArray[i];
      int i, j, bTemp;
      for (j = 0; j < iFilterLen - 1; j++)
      {
      for (i = 0; i < iFilterLen - j - 1; i++)
          {
        if (bTab[i] > bTab[i + 1])
            {
        bTemp = bTab[i];
            bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
         }
      }
      }
      if ((iFilterLen & 1) > 0)
    bTemp = bTab[(iFilterLen - 1) / 2];
      else
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
      return bTemp;
}

void getph()
{
  for(int i=0;i<10;i++)       //Get 10 sample value from the sensor for smooth the value
  {
    buf[i]=analogRead(pHSensorPin);
    delay(10);
  }
  for(int i=0;i<9;i++)        //sort the analog from small to large
  {
    for(int j=i+1;j<10;j++)
    {
      if(buf[i]>buf[j])
      {
        temp=buf[i];
        buf[i]=buf[j];
        buf[j]=temp;
      }
    }
  }
  avgValue=0;
  for(int i=2;i<8;i++)                      //take the average value of 6 center sample
    avgValue+=buf[i];
  float phValue1=(float)avgValue*5.0/1024/6; //convert the analog into millivolt
  phValue=3.5*phValue1;                      //convert the millivolt into pH value
}

void getlight()  {
  int sensorValue = analogRead(4);
  lightsensor=(float)(1023-sensorValue)*10/sensorValue;
}

and for good measure - Suprising annoyances

I had not fully appreciated how suscuptible the 1 wire implementation was to noise, this has meant that where I added a second waterproof DS18B20*1 digital temp sensor to my design. Unable to get hold of a Adafruit sensor to match I elected to go with a Amazon order as they had stock in and were availible for delivery - caveat emptor.

Notes

*1 - despite claiming to be a geniune DS18B20 sensor, I think my amazon special is not quite the real thing. Intermittant 85C readings - this tells you that the temp conversion request has not completed, -127C that the device isnt found and then spurious 100c plus readings doesnt make for very useful data. To make this more troublesome it also interfers with the outstanding Adafruit high temp DS18B20 waterproof sensor. Of all the things that have taken me down a rabbit hole, I did not expect it to be this of all things.

*2 - form over function. Where I wanted to add in the ability to measure the light level (based on another design change specifically relating to the placement of my sensor platform) i found what looked to be the PERFECT solution. Housed in a clear dome, the ambient light level sensor would give me a lux reading.

  • Evening: 0.001-0.02lx;
  • Moonlit night: 0.02-0.3lx;
  • Cloudy indoor: 5-50lx;
  • Cloudy outdoor: 50-500lx;
  • Sunny indoor: 100-1000lx;
  • Under summer noon light: about 10*6 lx;
  • Illumination when reading books: 50-60lx;
  • Home video standard illumination: 1400lx

I wanted to add this so in addition to understanding from note 1 above, the water temp at near surface and then at c40-50cm depth, the ammount of light reaching the surface of the pond. The I2C sensor should just be able to be connected up on the I2C bus along with the BME280 and no troubles ... or so i thought. Nestled in the ambient light sensor documentation is the note

This sensor is sealed by software IIC, and can not be used with other equipment or sensors using hardware IIC.

Now on my first read of this I took this to mean that the address of the device could not be changed (reasonable) and that in the event of an address conflict ... that would be a problem. Alas not,  I wish I had seen this before going to the avenue of including this in my build, firstly for the lost time to debugging and taking the position of 99% of the time it is something I have done, a bad solder joint, i made a mistake. Alas not. Thankfully whilst my annoyance with the ambient light sensor continues and the form is greater than the function it provides.

The root of the problem looks to be how I2C has been implemented for the sensor (SEN0390) and some messy bit banging which goes on, this results in the sensor not returning data and then anything else you have connected on the bus, not returning data. Take one sensor away, all is happy.

The Solution: (1) keep the sensor off the I2C bus (2) SDA/SCL define the pin input using two digital pins, as such:

DFRobot_B_LUX_V30B    myLux(13,5,6);//The sensor chip is set to 13 pins, SCL and SDA adopt default configuration

Why you need to include pin 13 in there is beyond me, if you dont, it wont work, if you do, it does. Also worth checking your own pin numbering on your device. I am using the Arduino Connector which is a breakoout for the grove sensors and needed me to swap pins 6 / 5 definition around  for SCL and SDA.

Useful i2c scanner

// --------------------------------------
// i2c_scanner
//
// Modified from https://playground.arduino.cc/Main/I2cScanner/
// --------------------------------------

#include <Wire.h>

// Set I2C bus to use: Wire, Wire1, etc.
#define WIRE Wire

void setup() {
  WIRE.begin();

  Serial.begin(9600);
  while (!Serial)
     delay(10);
  Serial.println("\nI2C Scanner");
}


void loop() {
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    WIRE.beginTransmission(address);
    error = WIRE.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknown error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

which when used identifies:

13:54:52.173 ->
13:54:57.095 -> Scanning...
13:54:57.142 -> I2C device found at address 0x4A  ! <-- ambient light sensor (but be damned if you can actually use the device address)
13:54:57.142 -> I2C device found at address 0x76  ! <--- this one we know if the BME280, as 0x76 is the default address and you can modify to 0x77 but changing the PCB jumper connection
13:54:57.188 -> done
13:54:57.188 ->

Bonus almost there video

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

Wiring Diagram

Please find below the wiring diagram for my setup. The base module to which all components are connected is the Arduino MKR Connection Carrier, this has the MKR1300 installed on top,  you do not need to worry about any additional connections, level shifting or supply voltage as this is all taken care of on the MKR Connection Carrier board (so many bonuses with using this) and it has a great price point, I paid £14-00 for mine.

This is completely compatible with the Grove connector system and modules. One point to note is to check the connection lines for your modules and the carrier board as some are NC - not connected.

You bring power into your system by providing 5.5v to the MKR Connection Carrier board. I achieved this with a low cost DC step down buck, in my case it takes the 12v supplied into the enclosure down to 5.5v DV. Importantly this is a stable and clean 5.5v.

image

Whats getting measured?

It occurs to me that I had not added a great deal of context for my garden pond. The below is a depth diagram, sounding if you will, which i produced from my original dig measurements, depth is in mm.

image

image

40mm holder - used to hold the 150mm long 40mm ID pipe which has a piece of insulation lagging and then the test instrument nestled inside

image

1515 aluminium slide profile - used to mount the 40mm holder for test equipment on the alu rail - snug fit.

image

40mm ID cap - used to seal the equipment holder pipe and route cable.

image

T-Junction - joins the horizonal and vertically aligned 1515 alu profile. Horizonal slides through completely, vertical wedges in place.

image

Base Bracket - connects the test assembly to the floating 110OD pipe. 1515 alu slides through

image

Weather base holder - 1 of these for your BME and amient light levels. The weather shieds stack on top, cables route through the bottom - drip loop Slight smile

image

Weather shield - I used 7 of these, secuted with 3mm rod and hot glue.

image

Cable stay and rescue bracket - mounted on the open sides of the pontoon and will be fitted with 6mm twisted wire run to keep my Floaty McTest Face device in approximately the same location in the pond

3DPARTS.zip

A zip with all the design files (autodesk fusion 360). Just in case I need to add any sort of fair use licences

Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)

  • Sign in to reply

Top Comments

  • DAB
    DAB over 3 years ago +1
    If you are getting EMI through the one wire, you can try twisting another wire around the data line and grounding both ends. That will cut some of the noise by establishing a ground barrier around your…
  • Agustin56
    Agustin56 over 3 years ago in reply to christophesky

    Yes, I understand that, but what function is used to exactly modify the collectionn time? In the example that includes the sensor library, I used the code that is commented out. My void setup is as follows:

    void setup() {
    Serial.begin(9600);
    myLux.begin();
    /* The setMode and readMode functions can be omitted. When not configured, the default configuration is the one used last time.
    When using the setMode function, its return value should be judged. If the return value is 1, the setting is successful. */

    while(!myLux.setMode(myLux.eManual,myLux.eCDR_0,myLux.eTime800ms));
    Serial.print("mode: ");
    Serial.println(myLux.readMode());

    }

    But it doesn't matter if I use eTime800ms or eTime25ms, the sensor response is still just as slow

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • christophesky
    christophesky over 3 years ago in reply to Agustin56

    If you adjust the collection time you can go from c800ms to 6.5ms, this does come with the cost of limiting the max LUX level you can reads if you wanted a longer sampling time, these are using the automatic modes

    At 6.25ms 200000 lux

    At 800ms 2938 lux

    I initially used in its default mode and then spent to much time adjusting to get it to work properly. If i needed to measure lux again, I would not use this sensor and chalk that up to experience.

    Good luck :) please let me know how you get on or if you find a better way to do it.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Agustin56
    Agustin56 over 3 years ago in reply to christophesky

    Hello, I am using the same ambient light sensor (SEN0390) but in its default configuration it has a very slow sampling time. I have tried to use the manual mode (eManual) of the library but I am not able to increase the speed with which the sensor updates the light intensity value.
    Do you know how I can make its collection time less, or did you use it in its default mode?

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • christophesky
    christophesky over 3 years ago

    It has happened. FInally happened.

    pH probe - alas it is no more.

    Temp probe 1 - alas it is no more, stainless steel enclosure has rusted and subsequently failed

    Turbidity - eroneous measurements not being fed back

    I am disappointed :(

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • christophesky
    christophesky over 3 years ago

    Bonus Video added Smiley

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube