Skip to content

Hardware

Talk about fun sensor hardware, MCUs, PCBs and how to power your sensors here.
1.8k Topics 18.3k Posts
  • Arduino Nano Every problem

    6
    1 Votes
    6 Posts
    123 Views
    OldSurferDudeO
    I bought the Every because it implied it was backward compatible with the nano. No, it's not, as we found out. Be that as it may, any word on a getting the Every working with mySensors?
  • Best VOC sensor for detecting a wide range of VOC's?

    3
    1 Votes
    3 Posts
    199 Views
    NeverDieN
    @eiten I haven't yet made any progress on finding a good VOC sensor, but along the way I did find out something interesting regarding CO2: namely, if you sleep with your bedroom door closed at night, then the odds are good that the CO2 levels rise to surprisingly high and unhealthy levels. The better CO2 sensors are factory calibrated and never again need recalibration for the life of the sensor (usually around 10 years or so), because they are used in HVAC systems to control fresh air intake to guarantee indoor air quality. As a for instance, here is one such CO2 sensor: https://www.digikey.com/en/products/detail/senseair/006-0-0008/15790694 At around $50 for just the sensor element itself, it's not exactly cheap, but then again, I'd say it's worth it, because who wants to be burdened by remembering to calibrate their CO2 sensors? Ideally, I'd like to find a sensitive VOC sensor that also will never require calibration. Nearly all, and maybe all, of the off-the-shelf IAQ montoring stuff that you might buy for, say, $300 or less seems to require periodic calibration. For that reason, this might be one of those occasions where build is rather than buy.
  • hlk-pm01 are to noisy for rfm69?

    5
    0 Votes
    5 Posts
    60 Views
    zboblamontZ
    @Tmaster Never assume the original PCB was just a circuit of components, the PCB can incorporate RF shields and antenna radio ground planes...
  • Sensors and more

    1
    0 Votes
    1 Posts
    28 Views
    No one has replied
  • Which one should i choose? PIR or microwave sensor

    8
    0 Votes
    8 Posts
    289 Views
    NeverDieN
    Supposedly PIR doesn't work through glass (e.g. if looking for motion through a window), whereas I presume a microwave sensor might still work.
  • New user has questions

    7
    0 Votes
    7 Posts
    80 Views
    C
    I am new in this forum and I have a question regarding mysensors and iobroker. I did not work with mysensors up to now. Since some weeks I use iobroker installed on a raspberrypi. Now I want to integrate my 433 Mhz doorbell in iobroker. I know, that there is an adapter for mysensors in iobroker. My question is: Is it possible to get a notification in iobroker if someone is pressing the button on my doorbell? As I understood, I have to connect the receiver to an arduino nano and connect the arduino to my rasberrypi on which iobroker is running.
  • Node with only sendBatteryLevel into Home Assistant

    9
    0 Votes
    9 Posts
    97 Views
    E
    Great! I'm glad it works and thank you very much for reporting back!
  • nRF5 Multi Sensor Board (12-14€)

    52
    5 Votes
    52 Posts
    22k Views
    monteM
    https://github.com/sandeepmistry/arduino-nRF5 Install this and find libraries for whatever sensors you have on that board. @basaksts said in nRF5 Multi Sensor Board (12-14€): Also I need an bootloader No, you really don't. You need ST-Link, or J-Link SWD programmer/debugger. Connect it to SWDIO, SWCLK, 3.3V and GND and program it using Arduino IDE.
  • My HW gives me wrong battery voltage

    7
    2
    0 Votes
    7 Posts
    77 Views
    zboblamontZ
    It's an awfully convoluted way of doing things but suspect your error lies in misunderstanding calculations mixing ints and floats and something screwy with your resistor bridge - It is always worth checking the bridge with a multimeter and raw voltage to verify the expectation. If you have 3v at the top of your voltage divider, you should be getting 0.9593v applied on the ADC pin which will be read as 892 against the 1.1v internal reference. The easiest way I found was to define a multiplier needed to derive the raw voltage, in this case (((R1+R2)x1.1)/R2) - For your resistor arrangement the max you can read is 3.4404v before exceeding the 1.1v internal reference. To reverse the ADC reading of 892 to raw voltage is (892x3.4404)/1023 = 2.9984 v. Perhaps this is a simpler way to do it float MULTIPLIER= (((1000+470)*1.1)/470);//Resistor bridge values in k and Vref int sensorValue = analogRead(BATTERY_SENSE_PIN); float batteryV = (sensorValue * MULTIPLIER)/1023.0; //Note the trailing decimal point on the 1023 for calculations involving floats
  • sx1262 and LLCC68 support.

    4
    0 Votes
    4 Posts
    105 Views
    C
    @__isded__ from what is explained in this page it seems it is based on the Semtech SX1278 : https://www.makerfabs.com/sx1278-lora-module-433m-10km-ra-02.html
  • Gateway + Oled ?

    7
    0 Votes
    7 Posts
    80 Views
    F
    Hello Jeelet, Thank you for the encouragements. Your advice to save (protect) the Oled screen is also welcome, thank you. My code expects it, the text is mini and moves every 3 seconds. Press a key and the menu returns. [image: 1674245032109-mysensors2d.png] Cordially.
  • 0 Votes
    32 Posts
    3k Views
    Edwin De BockE
    I just tested 2 led types with no flicker on my attiny circuit. It is funny, the expensive leds like from philips: Dimmable 3.8W Warm White have a flickering behavior . A cheap one available in Action from LSC 6.3W, Dim to Warm and 460 Lumen has no flickering behavior. Another one from Osram Par 1650: 5.5W Dimmable Warm White, 350 Lumen also has no flickering. The philips has the best Energy savings though : 4kWh compared to 7kWh for the LSC one. Is there a relation between energy savings and dim quality ?
  • Seeeduino Xiao nRF52840

    1
    0 Votes
    1 Posts
    31 Views
    No one has replied
  • Local Sensors on Raspberry Pi Gateway

    5
    0 Votes
    5 Posts
    59 Views
    OldSurferDudeO
    @mfalkvidd I finally got it to work. Look at my post on the Home Assistant forum. There is an amazing thing that someone in the MySensors world did that makes RPi I/O very easy! Just like the Arduino, one uses the code: pinMode(MphysicalPin, OUTPUT); I couldn't believe my eyes when I saw that. And then got double flabbergasted when I discovered that pin is the physical pin of the RPi! No mapping of GPIOi to the pins. Whew! So the I/O was easier than both of us could have imagined! @mfalkvidd if you know who did this, send them praise and thanks. OSD
  • Long Range again

    4
    0 Votes
    4 Posts
    107 Views
    N
    thanks for sharing!
  • E01-2G4M13S (NRF24L01+ PA + LNA)

    1
    2
    0 Votes
    1 Posts
    40 Views
    No one has replied
  • Sensor to measure amount of dripping water?

    10
    0 Votes
    10 Posts
    111 Views
    NeverDieN
    I would think that it's the ambient air temperature that affects how much condensate you collect, together with how much fuel was burned. After the initial warm-up that gets you to steady state, wouldn't the efficiency be constant? If the acidity is a problem, you can run the condensate over a bed of acid neutralizing rocks before it goes down your main drain. It's a thing.
  • Output voltage problem with StepUp Booster 3.3V

    19
    0 Votes
    19 Posts
    3k Views
    Y
    I would like to step up 3.3V from my power supply with the help of a dc-dc-boost converter to 5V and then I want to draw 500mA by placing a 10 Ohm resistor between the output-pin of the boost-converter and ground.
  • Microwave oven (no kidding :D)

    4
    2
    1 Votes
    4 Posts
    90 Views
    ben999B
    @skywatch great, thanks a lot for your suggestion. A bit of research on the internet educated me about these diodes :D looks like they already exist on the board that carries the relay. However, i deeply thank you for the info. This forum and internet in general is such a powerful tool :+1: @ejlane your concern is fully justified :+1: i also come from an engineering background and i like to think "worse case scenario". The more one look the more one find that the very vast majority or microwave ovens work the same way : there are 3 industrial switches built in the door lock. 2 of them are cabled on the "power side", one is for signaling ("software side"). So we are pretty safe on that matter. But you are so right about safety. Magnetron do emitt dangerous waves and capacitors and stuff packed in the oven can be deadly because of high voltage. Thanks both for suggestions. I will come back with updated sketches and beg for advice once more ;)
  • Is Ethernet shield for Nano usable in any way?

    2
    0 Votes
    2 Posts
    43 Views
    OldSurferDudeO
    @NeoX I use a Nano, Ethernet, LCD display, and GPS for an NTP server on my isolated network to provide the time for [suspect] cameras. #define VER 12.2 bool debug = false; // must be true to have debug statements go to serial /* NTP Time Server: Modified by Gregg Ferry using softwareserial instead of Serial1 using GY-GPS6MV2 This code is in the public domain. ver 12 time server gets time from Arduino clock instead of from gps */ #define enableEthernet false #define enableGPS true #define enableDisplay true #define minimizeSerialTraffic true #if enableEthernet // ethernet #include <SPI.h> // needed for Arduino versions later than 0018 #include <Ethernet.h> #include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008 // Time Server MAC address byte mac[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; // NTP Server public IP Address IPAddress ip(192, 168, 2, 130); // Time Server Port #define NTP_PORT 123 unsigned int localPort = 123; static const int NTP_PACKET_SIZE = 48; // buffers for receiving and sending data byte packetBuffer[NTP_PACKET_SIZE]; // An Ethernet UDP instance EthernetUDP Udp; int packetSize; // NTP since 1900/01/01 //#include <PGMWrap.h> //const uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //const or compiler complains const uint8_t daysInMonth [] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //const or compiler complains const unsigned long seventyYears = 2208988800UL; // to convert unix time to epoch #endif #if enableGPS // GPS #include <TinyGPS++.h> //GPS instance TinyGPSPlus tinyGPS; #include <NeoSWSerial.h> //#include <SoftwareSerial.h> #define rxPin 5 #define txPin 4 NeoSWSerial GPSSerial(rxPin, txPin); // CONNECT BT RX PIN TO ARDUINO txPin | CONNECT BT TX PIN TO ARDUINO rxPin char incharBefore=255; char inchar=255; #endif #if enableDisplay // Display #include "SSD1306Ascii.h" #include "SSD1306AsciiAvrI2c.h" #define I2C_ADDRESS 0x3C SSD1306AsciiAvrI2c oled; #endif bool TimeHasBeenSet = false; bool firstPass = true; //Time #include <Timezone.h> //#include "Time.h" TimeChangeRule myDST = {"PDT", Second, Sun, Mar, 2, -420}; // Daylight time = UTC - 7 hours TimeChangeRule mySTD = {"PST", First, Sun, Nov, 2, -480}; // Standard time = UTC - 8 hours Timezone myTZ(myDST, mySTD); TimeChangeRule *tcr; // pointer to the time change rule, use to get TZ abbrev time_t local; String timeString = "hh:mm:ss"; String dateString = "yyyy MMM dd"; const String localDaysOfWeek[] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" }; const String localMonthsOfYear[] = {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"}; uint8_t localDayOfWeek; uint8_t previousHour = 0; uint8_t previousMinute = 0; uint8_t previousSecond = 0; unsigned long timestamp1970; //-----------------------------------------------------------------------------------printTimes void printTimes(){ Serial.print(F("GPS ")); Serial.print(tinyGPS.date.year());Serial.print(F("/")); Serial.print(tinyGPS.date.month());Serial.print(F("/")); Serial.print(tinyGPS.date.day());Serial.print(F(" ")); Serial.print(tinyGPS.time.hour());Serial.print(F(":")); Serial.print(tinyGPS.time.minute());Serial.print(F(":")); Serial.println(tinyGPS.time.second()); Serial.print(F("UTC ")); Serial.print(year());Serial.print(F("/")); Serial.print(month());Serial.print(F("/")); Serial.print(day());Serial.print(F(" ")); Serial.print(hour());Serial.print(F(":")); Serial.print(minute());Serial.print(F(":")); Serial.println(second()); Serial.print(F("local ")); Serial.print(year(local));Serial.print(F("/")); Serial.print(month(local));Serial.print(F("/")); Serial.print(day(local));Serial.print(F(" ")); Serial.print(hour(local));Serial.print(F(":")); Serial.print(minute(local));Serial.print(F(":")); Serial.println(second(local)); Serial.print(F(" ")); Serial.print(dateString);Serial.print(F(" ")); Serial.println(timeString); } //-----------------------------------------------------------------------------------setTimeAndDateStrings void setTimeAndDateStrings(){ local = myTZ.toLocal(now(), &tcr); // two days ago -172800 char buf[32]; sprintf(buf, "%.2d:%.2d:%.2d",hour(local), minute(local), second(local)); timeString = String(buf); // char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer) // strcpy(m, monthShortStr(month(local))); // sprintf(buf, "%.2d %s %d",day(local), m, year(local)); // dateString = String(buf); sprintf(buf, "%.2d ",day(local)); dateString = String(buf); dateString += localMonthsOfYear[month(local)-1]; sprintf(buf," %d",year(local)); dateString += String(buf); localDayOfWeek = weekday(local)-1; } #if enableGPS //-----------------------------------------------------------------------------------getgps static bool getgps() { // and update arduino time if (GPSSerial.available()==0) return false; // while (GPSSerial.available()) { incharBefore = inchar; inchar = GPSSerial.read(); tinyGPS.encode(inchar); if (!TimeHasBeenSet) Serial.print(inchar); // } if ((inchar != 10) || (incharBefore != 13)) return false; // make sure to full NMEA statement was received inchar = 0; incharBefore = 0; // NMEA statement received, reset terminators if(tinyGPS.time.isValid()){ /* * setTime( tinyGPS.time.hour(), tinyGPS.time.minute(), tinyGPS.time.second(), tinyGPS.date.day(), tinyGPS.date.month(), tinyGPS.date.year() ); */ int hh=tinyGPS.time.hour(); int mm=tinyGPS.time.minute(); int ss=tinyGPS.time.second(); int DD=tinyGPS.date.day(); int MM=tinyGPS.date.month(); int YY=tinyGPS.date.year(); setTime(hh,mm,ss,DD,MM,YY); local = myTZ.toLocal(now(), &tcr); //get the local time setTimeAndDateStrings(); if (!TimeHasBeenSet) printTimes(); TimeHasBeenSet = true; return true; } else { return false; } } #endif #if enableDisplay //-----------------------------------------------------------------------------------displayGPStimeSetTheTime void displayGPStimeSetTheTime(bool TimeSetByGPS){ oled.setCursor(0,0); // Start at top-left corner if (TimeSetByGPS) oled.print(F(" ")); else oled.print(F("!")); } //-----------------------------------------------------------------------------------displayAwaitingGPS void displayAwaitingGPS() { oled.clear(); oled.setCursor(0,0); // Start at top-left corner oled.println(F("NTP Server")); oled.println(F(" Awating")); oled.println(F(" GPS Lock ")); Serial.println(F(" Awating GPS Lock ")); } //-----------------------------------------------------------------------------------displayNewDay void displayNewDay(){ previousHour = hour(local); previousMinute= minute(local); previousSecond = second(local); oled.clear(); oled.setCursor(12,0); // center time string oled.print(timeString); uint8_t s = (10-localDaysOfWeek[localDayOfWeek].length())*6; oled.setCursor(s,3); oled.print(localDaysOfWeek[localDayOfWeek]); oled.setCursor(0,6); oled.print(dateString); } //-----------------------------------------------------------------------------------displayTime void displayTime(){ // digital clock display of the time if ((second(local)==0 && minute(local)==0 && hour(local)==0) || firstPass){ // new day firstPass = false; displayNewDay(); } else { if (hour(local) != previousHour){ previousHour = hour(local); oled.setCursor(12,0); oled.print(timeString); } else { if (minute(local) != previousMinute){ previousMinute= minute(local); oled.setCursor(48,0); oled.print(timeString.substring(3)); } else { if (second(local) != previousSecond){ previousSecond = second(local); oled.setCursor(84,0); oled.print(timeString.substring(6)); } } } } } // send to serial monitor #else void displayGPStimeSetTheTime(bool TimeSetByGPS){ } void displayAwaitingGPS() { Serial.println(F(" Awating GPS Lock ")); } void displayTime(){ #if !minimizeSerialTraffic Serial.println(); printTimes(); #endif } #endif //-----------------------------------------------------------------------------------setup #if enableEthernet void setupEthernet(){ // start the Ethernet and UDP: Ethernet.begin(mac,ip); Udp.begin(localPort); Serial.print(Ethernet.localIP()); Serial.print(F(" "));Serial.println(NTP_PORT); } #endif #if enableGPS void setupGPS(){ GPSSerial.begin(9600); // start GPS module UART // Disable everything but $GPRMC // Note the following sentences are for UBLOX NEO6MV2 GPS GPSSerial.write("$PUBX,40,GLL,0,0,0,0,0,0*5C\r\n"); GPSSerial.write("$PUBX,40,VTG,0,0,0,0,0,0*5E\r\n"); GPSSerial.write("$PUBX,40,GSV,0,0,0,0,0,0*59\r\n"); GPSSerial.write("$PUBX,40,GGA,0,0,0,0,0,0*5A\r\n"); GPSSerial.write("$PUBX,40,GSA,0,0,0,0,0,0*4E\r\n"); } #endif #if enableDisplay void setupDisplay(){ oled.begin(&Adafruit128x64, I2C_ADDRESS); oled.setFont(System5x7); oled.set2X(); } #endif void setup() { Serial.begin(115200); Serial.print("NTP Server with display version ");Serial.println(VER); #if enableDisplay setupDisplay(); #endif displayAwaitingGPS(); #if enableEthernet setupEthernet(); #endif #if enableGPS setupGPS(); #endif } //-----------------------------------------------------------------------------------loop void loop() { /* while (Serial.available()){ char inChar = Serial.read(); if (inChar == 'd' || inChar == 'D') { debug = !debug; if (debug) Serial.println(F("debug is ON"));else Serial.println(F("debug is off")); } } */ #if enableGPS if (getgps()){ if(TimeHasBeenSet) displayTime(); } #endif #if enableEthernet // if there's data available, read a packet packetSize = Udp.parsePacket(); if(packetSize) processNTP(); #endif } #if enableEthernet //-----------------------------------------------------------------------------------numberOfSecondsSince1900Epoch unsigned long int numberOfSecondsSince1900Epoch(uint16_t y, uint8_t m, uint8_t d, uint8_t h, uint8_t mm, uint8_t s) { if (y >= 1970) y -= 1970; uint16_t daysLocal = d; for (uint8_t i = 1; i < m; ++i) daysLocal += daysInMonth[i - 1]; // for (uint8_t i = 1; i < m; ++i) // daysLocal += pgm_read_byte(daysInMonth + i - 1); if (m > 2 && y % 4 == 0) ++daysLocal; daysLocal += 365 * y + (y + 3) / 4 - 1; return daysLocal*24L*3600L + h*3600L + mm*60L + s + seventyYears; } //-----------------------------------------------------------------------------------processNTP void processNTP() { Udp.read(packetBuffer,NTP_PACKET_SIZE); IPAddress Remote = Udp.remoteIP(); int PortNum = Udp.remotePort(); /* if (debug) { Serial.println(); Serial.print("Received UDP packet size "); Serial.println(packetSize); Serial.print("From "); for (int i =0; i < 4; i++) { Serial.print(Remote[i], DEC); if (i < 3) { Serial.print("."); } } Serial.print(", port "); Serial.print(PortNum); byte LIVNMODE = packetBuffer[0]; Serial.print(" LI, Vers, Mode :"); Serial.print(packetBuffer[0],HEX); byte STRATUM = packetBuffer[1]; Serial.print(" Stratum :"); Serial.print(packetBuffer[1],HEX); byte POLLING = packetBuffer[2]; Serial.print(" Polling :"); Serial.print(packetBuffer[2],HEX); byte PRECISION = packetBuffer[3]; Serial.print(" Precision :"); Serial.println(packetBuffer[3],HEX); for (int z = 0; z < NTP_PACKET_SIZE; z++) { Serial.print(packetBuffer[z],HEX); if (((z+1) % 4) == 0) { Serial.println(); } } Serial.println(); } // end of debug statements */ packetBuffer[0] = 0b00100100; // LI, Version, Mode packetBuffer[1] = 1 ; // stratum packetBuffer[2] = 6 ; // polling minimum packetBuffer[3] = 0xFA; // precision packetBuffer[7] = 0; // root delay packetBuffer[8] = 0; packetBuffer[9] = 8; packetBuffer[10] = 0; packetBuffer[11] = 0; // root dispersion packetBuffer[12] = 0; packetBuffer[13] = 0xC; packetBuffer[14] = 0; /* uint16_t y=year(); uint8_t m=month(); uint8_t d=day(); uint8_t h=hour(); uint8_t mm=minute(); uint8_t s=second(); if (y >= 1970) y -= 1970; uint16_t daysLocal = d; for (uint8_t i = 1; i < m; ++i) daysLocal += daysInMonth[i - 1]; if (m > 2 && y % 4 == 0) ++daysLocal; daysLocal += 365 * y + (y + 3) / 4 - 1; timestamp1970 = daysLocal*24L*3600L + h*3600L + mm*60L + s + seventyYears; */ // uint16_t utcYY=year(); // uint8_t utcMM=month(); // uint8_t utcDD=day(); // uint8_t utchh=hour(); // uint8_t utcmm=minute(); // uint8_t utcss=second(); // timestamp1970 = numberOfSecondsSince1900Epoch(utcYY,utcMM,utcDD,utchh,utcmm,utcss); // timestamp1970 = numberOfSecondsSince1900Epoch(2022,4,30,10,10,10); timestamp1970 = numberOfSecondsSince1900Epoch(year(),month(),day(),hour(),minute(),second()); /* * timestamp1970 = numberOfSecondsSince1900Epoch( tinyGPS.date.year(), tinyGPS.date.month(), tinyGPS.date.day(), tinyGPS.time.hour(), tinyGPS.time.minute(), tinyGPS.time.second() ); */ unsigned long tempval = timestamp1970; packetBuffer[12] = 71; //"G"; packetBuffer[13] = 80; //"P"; packetBuffer[14] = 83; //"S"; packetBuffer[15] = 0; //"0"; // reference timestamp1970 packetBuffer[16] = (tempval >> 24) & 0XFF; tempval = timestamp1970; packetBuffer[17] = (tempval >> 16) & 0xFF; tempval = timestamp1970; packetBuffer[18] = (tempval >> 8) & 0xFF; tempval = timestamp1970; packetBuffer[19] = (tempval) & 0xFF; packetBuffer[20] = 0; packetBuffer[21] = 0; packetBuffer[22] = 0; packetBuffer[23] = 0; //copy originate timestamp from incoming UDP transmit timestamp packetBuffer[24] = packetBuffer[40]; packetBuffer[25] = packetBuffer[41]; packetBuffer[26] = packetBuffer[42]; packetBuffer[27] = packetBuffer[43]; packetBuffer[28] = packetBuffer[44]; packetBuffer[29] = packetBuffer[45]; packetBuffer[30] = packetBuffer[46]; packetBuffer[31] = packetBuffer[47]; //receive timestamp packetBuffer[32] = (tempval >> 24) & 0XFF; tempval = timestamp1970; packetBuffer[33] = (tempval >> 16) & 0xFF; tempval = timestamp1970; packetBuffer[34] = (tempval >> 8) & 0xFF; tempval = timestamp1970; packetBuffer[35] = (tempval) & 0xFF; packetBuffer[36] = 0; packetBuffer[37] = 0; packetBuffer[38] = 0; packetBuffer[39] = 0; //transmitt timestamp packetBuffer[40] = (tempval >> 24) & 0XFF; tempval = timestamp1970; packetBuffer[41] = (tempval >> 16) & 0xFF; tempval = timestamp1970; packetBuffer[42] = (tempval >> 8) & 0xFF; tempval = timestamp1970; packetBuffer[43] = (tempval) & 0xFF; packetBuffer[44] = 0; packetBuffer[45] = 0; packetBuffer[46] = 0; packetBuffer[47] = 0; // Reply to the IP address and port that sent the NTP request Udp.beginPacket(Remote, PortNum); Udp.write(packetBuffer,NTP_PACKET_SIZE); Udp.endPacket(); } #else void processNTP() {} #endif

16

Online

11.7k

Users

11.2k

Topics

113.1k

Posts