Arduino driver for seesaw multi-use chip
Check out the documentation for a listing and explanation of the available methods!
Arduino library driver for seesaw multi-use chip
Arduino driver for seesaw multi-use chip
Check out the documentation for a listing and explanation of the available methods!
This issue occurs with both of the basic examples from the Arduino and Circuitython libraries with
an I2C QT_ROTARY_Encoder PID (4991). I have encountered it with both a QTPY RP2040 (Circuitpython) and a QTPY M0 (Arduino).
The encoder position does not always return to the same starting value after turning the encoder.
It can be reproduced in two ways:
1)Note the starting value. Rapidly turn the encoder back and forth several times returning to the starting point. The returned value will not always be the same as the starting value.
2) Note the starting value. Gently turn the encoder, but do not go to the next indent. Sometimes the encoder will report a change in position when no change has occurred.
I expect that this is also what it happening in 1). The encoder is sometimes counting a partial step.
Hi,
This repository doesn't have a license file, and there aren't license headers in the main source files.
Could an explicit license be added?
Thanks.
Simon
The Adafruit I2C Quad Rotary Encoder Breakout with NeoPixel is not being found with an i2c scan using the Arduino GIGA. (Arduino code base)
The GIGA works great with a NeoKey 1x4 (SAMD09 based).
Moving the Quad Rotary Encoder to an ESP32 also works fine.
There is an I2C communication fail happening between the:
GIGA STM32 <--> Quad Rotary Encoder ATtiny817
Forum thread has additional testing details. Scope traces courtesy of @fddrsn.
Triangles drawn to display for LEFT / RIGHT joystick seem to be swapped in examples/miniTFTWing/basic/basic.ino.
More info here:
https://forums.adafruit.com/viewtopic.php?f=19&t=144068
I've also recreated the issue.
Multiple calls toanalog_write
generate an IOError. Adding a time.sleep
between calls fixes it.
I used the seesaw soil sensor example which comes with version 1.4.0 of the soli sensor library and the capacitance logged is the same as the temperature. Ie if the logged temperature is, for example, 25.87*C the capacitance is 25 etc.
Reverting to version 1.3.1 of the seesaw library the capacitance is within the range expected, ie with the sensor in the air it is greater than 300.
The sensor is connected as per https://learn.adafruit.com/adafruit-stemma-soil-sensor-i2c-capacitive-moisture-sensor/arduino-test
Hi everyone!
This discussion is about precision, clarity and usefulness of code documentation.
This "issue" is not meant to criticize the work done, but to have everyone think about the usefulness of the comments and documentation they write for their code.
I'm sure most have seen well written documentation that is clear, precise and useful as well as useless superficial documentation that tells nothing but what everybody already knew or could figure out in five minutes. I, like many others I am sure, appreciate the effort of preparing the code for documentation, but sometimes, the info given is somewhat "not useful"...
An unfortunate example from here:
/**************************************************************************/
/*!
@brief set the value of the backlight
@param value the backlight value to set
*/
/**************************************************************************/
void Adafruit_TFTShield18::setBacklight(uint16_t value){
uint8_t cmd[] = {0x00, (uint8_t)(value >> 8), (uint8_t)value};
this->write(SEESAW_TIMER_BASE, SEESAW_TIMER_PWM, cmd, 3);
}
I mean, I can guess from the function name that it sets backlight and that I should pass it a uint16_t, but what value? It kinda states the obvious, without giving any new, useful information.
Searching the source code was of no help, and I could not find the code for the PWM module for Seesaw. If I had, I could have figured what it wrote to the CPU registers and find what values the chip expected. I searched everywhere I knew and read all I could find on Seesaw, including here. But I had to raise an issue to get an answer (Thanks a lot BTW!).
The updated code from the Adafruit-ST7735-Library\examples\TFTShield18_seesaw\shieldtest\shieldtest.ino now gives more information than the current documentation:
// Set backlight on fully
// ss.setBacklight(TFTSHIELD_BACKLIGHT_ON);
// Or you can set the backlight one third on
// ss.setBacklight(TFTSHIELD_BACKLIGHT_ON / 3);
// Or dim it up
for (int32_t i=TFTSHIELD_BACKLIGHT_OFF; i<TFTSHIELD_BACKLIGHT_ON; i+=100) {
ss.setBacklight(i);
delay(1);
}
Yay! I know how to dim the backlight and what values it will accept! THANKS!
But unfortunately, documentation like the following isn't useful for anybody but those who already know what it does. Then why write it? Don't do this please!
@brief set the value of the backlight
@param value the backlight value to set
Maybe this documentation is barely in Alpha stage and just the skeleton of what will be the true documentation? In that case, great! I'm looking forward to its completion!
But right now, it's not very useful.
And still, I have no idea what this does nor why/when I should use it:
/**************************************************************************/
/*!
@brief set the PWM frequency for the backlight
@param freq the frequency to set the backlight to
*/
/**************************************************************************/
void Adafruit_TFTShield18::setBacklightFreq(uint16_t freq){
uint8_t cmd[] = {0x0, (uint8_t)(freq >> 8), (uint8_t)freq};
this->write(SEESAW_TIMER_BASE, SEESAW_TIMER_FREQ, cmd, 3);
}
As you can see, without good documentation and comments, that code is like a big black box. What is the usefulness of setting the backlight frequency? When should I use it? What are the acceptable values?
In itself, for someone who can read code, the code is the ultimate documentation. But without the context in the programmer's head, some information can be lost (Why is it done that way?) and fixes go unnoticed (Doing ___ and ___ to avoid ___ bug in ___.). It may take a significant time to find your answer too!
Will you remember why/how/what in five years when you modify your code? Don't take a chance, document your code!
Finally, I want to thank the whole Adafruit team who made my purchases useful and fun to use! Yes, I had glitches, but they where taken care of quickly and to my entire satisfaction! Sure, you could find cheaper stuff out there, but the quality of the hardware and availability of supported code will make your experience enjoyable! Without good quality parts, ready to use tested code and support, how much time will you lose? I won't!
Martin
List the steps to reproduce the problem below (if possible attach a sketch or
copy the sketch code in too):
Call seesaw_NeoPixel.clear()
with DEBUG_SERIAL
enabled
Neopixel is not updated and the following error is printed:
I2CDevice could not write such a large buffer
Root cause:
Neopixel::clear()
calls Adafruit_seesaw::write(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_BUF, writeBuf, 32)
with a size of 32 bytes, while seesaw::write()
then prepends a prefix of size prefix_len=2
bytes for a total of 34 bytes.Fix:
Adafruit_seesaw::write()
from Neopixel::clear()
.Caller:
void seesaw_NeoPixel::clear() {
// Clear local pixel buffer
memset(pixels, 0, numBytes);
// Now clear the pixels on the seesaw
uint8_t writeBuf[32];
memset(writeBuf, 0, 32);
for(uint8_t offset = 0; offset < numBytes; offset += 32-4) {
writeBuf[0] = (offset >> 8);
writeBuf[1] = offset;
this->write(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_BUF, writeBuf, 32);
}
}
Callee:
bool Adafruit_seesaw::write(uint8_t regHigh, uint8_t regLow,
uint8_t *buf = NULL, uint8_t num = 0) {
uint8_t prefix[2];
prefix[0] = (uint8_t)regHigh;
prefix[1] = (uint8_t)regLow;
if (_flow != -1)
while (!::digitalRead(_flow))
yield();
if (!_i2c_dev->write(buf, num, true, prefix, 2)) {
return false;
}
return true;
}
Arduino board: ESP32 DEVKIT V1
Arduino IDE version (found in Arduino -> About Arduino menu): Arduino 1.6/1.8 in Visual Studio 2019 set for Adafruit ESP feather. Using Visual Micro extension to Visual Studio.
I wrote this up in the Adafruit forums. See the last 3 entries by Jim_Frankfort in this thread: https://forums.adafruit.com/viewtopic.php?f=19&t=162556&start=15,
In brief: TouchRead doesn not work on ESP32 DEVKIT V1 using Adafruit soilsensor. Code worked with Arduino Mega 2560 but hung in read() when executed on ESP32.
Issue seemed to be duration of optional delay between request sent to soilsensor and reading soilsensor. If delay too brief, device returns 65535 and code hangs because
while loop continues to request read until returns something other than 65535, which it never does.
Solution is to lengthen delay and only try a finite number of times. A delay of 5000 took only a single call to read to get
a valid result, where as a delay of 2500 took 2 reads, 1000 took 3 reads, and 500 took 4 or 8 reads. There are other ways that this code will hang. E.g. if the soil sensor loses power, it returns 65535.
Instead of using a while loop, I used a for loop with a max of 255 tries before returning. In addition to tweaking the code so that it doesn't hang, please consider consider adding an error flag. I'm working on a data logger that has a lot of sensors.....sure would be good for the system to report sensor failures rather than just stop working. Thanks......jimf
I'm using the demo code from the learning site. If I put:
for (int i = 0; i < 4; i++) {
ss.setEncoderPosition(50, i);
}
for (int i = 0; i < 4; i++) {
Serial.println(ss.getEncoderPosition(i));
}
at the end of the setup code, I print 4 zeros. I don't think it's a bad board, because everything else seems to work.
P.S. I'm using seesaw library version 1.7.3
The soil sensor LED or PA27 cannot be controlled via seesaw.
Because the CONFIG_ACTIVITY_LED define for board SOIL defaults to 0. So
#define CONFIG_GPIO_MASK (((unsigned long long) 0xFFFFFFFFFFFFFFFF) ^ ( ((uint64_t)CONFIG_USB << CONFIG_USBPIN_USB_DM) | ((uint64_t)CONFIG_USB << CONFIG_USBPIN_USB_DP) \
| ((uint64_t)CONFIG_ADDR << PIN_ADDR_0) | ((uint64_t)CONFIG_ADDR << PIN_ADDR_1) \
| ((uint64_t)CONFIG_ADDR_2 << PIN_ADDR_2) | ((uint64_t)CONFIG_ADDR_3 << PIN_ADDR_3) \
| ((uint64_t)CONFIG_ADDR_4 << PIN_ADDR_4) \
| ((uint64_t)CONFIG_ACTIVITY_LED << PIN_ACTIVITY_LED) | ((uint64_t)CONFIG_POWER_SENSE << CONFIG_POWER_SENSE_NEOPIX_PIN) \
Bit 27 is always masked out! What's the point of the LED if you can't use it?
I am using a lot of GPIOs and have now exceeded the number available on one SEESAW ATtiny817 board. I would like to chain two with the I2C connectors. Does each board need to have its own I2C address? I can't find any Examples (Arduino) that show how to set this up and how to specify which board I am reading or writing to. Does each board have to have its own interrupt line to signal GPIO transitions or are they ganged? Can you bulk-poll both boards with one command?
Can you please point me to that information or some sample code? Ideally, it should be in the board's documentation, but I could not find it, nor in the Seesaw Examples.
In the document, one should be able to change the I2C address by calling setI2CAddr().
The default address of Adafruit Mini I2C STEMMA QT Gamepad is 0x50.
However, I have try using setI2CAddr() as well as try calling EEPROMWrite8(SEESAW_EEPROM_I2C_ADDR, newAddress) directly and then call ss.begin(newAddress).
Calling ss.begin(newAddress) would return false.
The function can actually store the new address to EEPROM. I have verified this by calling getI2CAddr(), even after the replug the power cable.
But, the I2C address that can used to ss.begin() must still be the old one, 0x50.
Look like the gamepad does not use or care the I2C address from EEPROM.
more detail on this post https://forums.adafruit.com/viewtopic.php?t=205373
Thanks a lot
Matt
Thank you for opening an issue on an Adafruit Arduino library repository. To
improve the speed of resolution please review the following guidelines and
common troubleshooting steps below before creating the issue:
Do not use GitHub issues for troubleshooting projects and issues. Instead use
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
something isn't working as expected. In many cases the problem is a common issue
that you will more quickly receive help from the forum community. GitHub issues
are meant for known defects in the code. If you don't know if there is a defect
in the code then start with troubleshooting on the forum first.
If following a tutorial or guide be sure you didn't miss a step. Carefully
check all of the steps and commands to run have been followed. Consult the
forum if you're unsure or have questions about steps in a guide/tutorial.
For Arduino projects check these very common issues to ensure they don't apply:
For uploading sketches or communicating with the board make sure you're using
a USB data cable and not a USB charge-only cable. It is sometimes
very hard to tell the difference between a data and charge cable! Try using the
cable with other devices or swapping to another cable to confirm it is not
the problem.
Be sure you are supplying adequate power to the board. Check the specs of
your board and plug in an external power supply. In many cases just
plugging a board into your computer is not enough to power it and other
peripherals.
Double check all soldering joints and connections. Flakey connections
cause many mysterious problems. See the guide to excellent soldering for examples of good solder joints.
Ensure you are using an official Arduino or Adafruit board. We can't
guarantee a clone board will have the same functionality and work as expected
with this code and don't support them.
If you're sure this issue is a defect in the code and checked the steps above
please fill in the following fields to provide enough troubleshooting information.
You may delete the guideline and text above to just leave the following details:
Arduino board: INSERT ARDUINO BOARD NAME/TYPE HERE
ESP8266 Huzzah
Arduino IDE version (found in Arduino -> About Arduino menu): INSERT ARDUINO
VERSION HERE
8.1.12 running on Linux Mint
List the steps to reproduce the problem below (if possible attach a sketch or
copy the sketch code in too): LIST REPRO STEPS BELOW
Install SeeSaw library
open the "examples/soil_sensor/soilsensor_example/soilsensor_example.ino" sketch
write, the sketch and observe the temperature. (currently i see: 34.99998)
Currently a professional thermometer shows 30C
This is nearly a 5C difference.
Is this expected, the website states: "maybe good to + or - 2 degrees Celsius"
this is a slightly larger difference.
The other day, I bought some NeoTrellis and started to make my work.
I found a strange operation when I pressed more than one key at once.
The issue is next:
o When I pressed two keys at one, remaining keys on same column are strangely on.
o In basic example code, key events are correctly come (detecting key pressing generates key event. this case 'detecting' include hardware's wrong key press detecting.).
o getKeypadCount() [line 83 of Adafruit_NeoTrellis.cpp] returns 1~4. (I think 1 or 2 is correct. 3 and 4 is incorrect state of this issue.)
o Using INT pin or not has no relation.
o Using KEYPAD_EDGE_HIGH and KEYPAD_EDGE_LOW causes same act.
o There are another issues I found. One is lockup problem, and the other is key release event no coming.
I tested with Adafruit's original example code named 'basic', using Arduino UNO.
See attached image.
I uploaded a video on my repository.
https://github.com/toolbits/seesaw/blob/master/%7Eresearch/neotrellis.m4v
So, I doubt seesaw library that has some bugs maybe.
I doubt the code nearby next code:
In https://github.com/adafruit/seesaw/blob/master/source/AOKeypad.cpp
226 gpio_outset_bulk(PORTA, keypad_output_masks[i]);
227 //short delay
228 for(int __tmr = 0; __tmr<100; __tmr++) asm volatile ("NOP;");
229 in = gpio_read_bulk() & KEYPAD_INPUT_MASK; //read everything at once
Or interruption problem of ARM chip. Register remembering and restoring problem, etc...
Loading configuration...
Initializing packages...
Preparing boards...
Verifying...
_basic_multi:_1:33: error: Adafruit_RGBTrellis.h: No such file or directory
compilation terminated.
exit status 1
Looks like someone is preparing for a new board and pushed a file (without the .h accompanying. This makes other pull requests like mine (for a touch example) fail.
Hi Adafruit.
First, thanks. I love the Adafruit libraries They make me buy from Adafruit.
You may have an error in Seesaw library 1.4.0 as it applies to the STEMMA soil sensors.
The recent Adafruit_seesaw library v 1.4.0 causes my 2 STEMMA soil sensors to read radically different moisture values from the values they both showed prior to library version 1.4.0. Temperature values were not impacted.
Seesaw library version 1.4.0 was installed using Arduino IDE 1.8.13 Win 10 Library Manager.
I am compiling for ESP8266 NodeMCU 1.0 (ESP-12E Module).
Using Seesaw Library versions 1.3.0 and 1.3.1, both my STEMMA soil sensors gave moisture readings in the 200-1200 range.
Introducing library v 1.4.0 changed both soil sensor readings to 20-22 from the previous readings around 600.
Reverting back to library versions 1.3.0 or 1.3.1 restored the previous moisture readings at the 600 range they had been for weeks.
Your seesaw library example code works. Here's simplified code I extracted from my own sketch.
#define SERIAL_SPEED 230400
#define SKETCH_NAME "Seesaw_Soil_Sensor_Example_Simple"
// This from Adafruit doc https://learn.adafruit.com/adafruit-stemma-soil-sensor-i2c-capacitive-moisture-sensor/arduino-test
#include "Adafruit_seesaw.h" // Also uses Adafruit Unified Sensor library
// Data object for the STEMMA Soil Sensor
Adafruit_seesaw soilSensor;
void setup()
{
// Never enough good printouts
Serial.begin ( SERIAL_SPEED );
delay ( 500 );
Serial.println ( "\n\n=============================================\n=============================================" );
Serial.println ( SKETCH_NAME );
initializeSeesawSoilSensor(); // set up all sensors
} //end setup
void loop()
{
readSeesawSoilSensorReadings();
delay ( 3000 );
} // end loop
void initializeSeesawSoilSensor() // soil temp and moisture
{
// This from Adafruit doc https://learn.adafruit.com/adafruit-stemma-soil-sensor-i2c-capacitive-moisture-sensor/arduino-test
Serial.println ( "Adafruit Seesaw Soil Sensor initialization" );
if ( soilSensor.begin ( 0x36 ) )
{
Serial.print ( "Soil Sensor found. version: " ); Serial.println ( soilSensor.getVersion(), HEX );
}
else
{
Serial.println ( "No soil sensor found. " );
}
Serial.println();
} // end initializeSeesawSoilSensors
void readSeesawSoilSensorReadings()
{
// This from Adafruit doc https://learn.adafruit.com/adafruit-stemma-soil-sensor-i2c-capacitive-moisture-sensor/arduino-test
Serial.println ( "readSeesawSoilSensorReadings called..." );
int moisture;
float temperatureC, temperatureF;
Serial.print ( "\nReading soil sensor." );
uint32_t timestamp = millis();
temperatureC = soilSensor.getTemp(); // Grab the Soil temperature
moisture = soilSensor.touchRead(0); // Capacitive moisture, too (int)
timestamp = millis() - timestamp;
temperatureF = temperatureC * 9.0/5.0 + 32.0; // convert to Farenheit
Serial.print ( "Temperature C: " ); Serial.print ( temperatureC ); Serial.println ( " degrees C" );
Serial.print ( "Temperature F: " ); Serial.print ( temperatureF ); Serial.println ( " degrees F" );
Serial.print ( "Moisture: " ); Serial.print ( moisture ); Serial.println ( " units" );
Serial.print ( "Read duration (ms): " ); Serial.println ( timestamp ); Serial.println();
} // end readSeesawSoilSensorReadings
Anyone have any idea how to calibrate the Adafruit STEMMA Soil Sensor - I2C Capacitive Moisture Sensor to give VWC (Voulmetric water content)
this is the code used:
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
void setup() {
Serial.begin(115200);
Serial.println("seesaw Soil Sensor example!");
if (!ss.begin(0x36)) {
Serial.println("ERROR! seesaw not found");
while(1);
} else {
Serial.print("seesaw started! version: ");
Serial.println(ss.getVersion(), HEX);
}
}
void loop() {
float tempC = ss.getTemp();
uint16_t capread = ss.touchRead(0);
Serial.print("Temperature: "); Serial.print(tempC); Serial.println("*C");
Serial.print("Capacitive: "); Serial.println(capread);
delay(100);
}
There is a problem as soon as one uses Adafruit_seesaw.h with Arduino code generated by the Arduino IOT Cloud which includes:
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
Here is my code:
Main Code:
#include "arduino_secrets.h"
#include "thingProperties.h"
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
void setup() {
Serial.begin(115200);
Serial.println("seesaw Soil Sensor example!");
if (!ss.begin(0x36)) {
Serial.println("ERROR! seesaw not found");
while(1);
} else {
Serial.print("seesaw started! version: ");
Serial.println(ss.getVersion(), HEX);
}
initProperties();
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(4);
ArduinoCloud.printDebugInfo();
}
void loop() {
float tempC = ss.getTemp();
uint16_t capread = ss.touchRead(0);
int moist = map(capread, 338, 570, 0, 100);
Serial.print("seesaw started! version: ");
Serial.println(ss.getVersion(), HEX);
Serial.print("Temperature: "); Serial.print(tempC); Serial.println("*C");
Serial.print("Capacitive: "); Serial.println(capread);
Serial.print("Moist: "); Serial.println(moist);
Serial.println();
delay(1000);
}
thingProperties.h:
// Code generated by Arduino IoT Cloud, DO NOT EDIT.
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
const char THING_ID[] = "d0d57085-4094-465b-9743-2d2a320e1396";
const char SSID[] = SECRET_SSID; // Network SSID (name)
const char PASS[] = SECRET_PASS; // Network password (use for WPA, or use as key for WEP)
int pallas_Ping;
float pallas_i2c_Temp;
int pallas_ic2_Moisture;
void initProperties(){
ArduinoCloud.setThingId(THING_ID);
ArduinoCloud.addProperty(pallas_Ping, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(pallas_i2c_Temp, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(pallas_ic2_Moisture, READ, ON_CHANGE, NULL);
}
WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);
The correct output is when the line "ArduinoCloud.begin(ArduinoIoTPreferredConnection);" is commented out and is:
23:30:26.618 -> seesaw started! version: FBA278F
23:30:26.618 -> Temperature: 26.17*C
23:30:26.618 -> Capacitive: 346
23:30:26.618 -> Moist: 3
As soon as this line is enabled the output becomes:
23:36:37.945 -> seesaw started! version: 19000000
23:36:37.945 -> Temperature: 25.64*C
23:36:37.945 -> Capacitive: 65535
23:36:37.945 -> Moist: 28102
I have also posted about this on the Adafruit forums but haven't received any response. After doing extensive investigations on this I'm pretty confident this isn't a simple PEBKAC issue but I'm unsure if it's a hardware issue, library issue, or something else I'm missing.
Hardware:
Scenario:
I am trying to use an interrupt to respond to button presses from the Joy Featherwing without needing to monitor the button state in a loop.
I'm seeing two suspicious behaviors:
The only way I seem to be able to actually read the state of the Joy Featherwing is from within the main execution loop, which is exactly what I'm trying to avoid.
Here is some sample code:
#include "Adafruit_seesaw.h"
#define BUTTON_RIGHT 6
#define BUTTON_DOWN 7
#define BUTTON_LEFT 9
#define BUTTON_UP 10
#define BUTTON_SEL 14
#define JOY_IRQ_PIN 14
static uint32_t s_button_mask = (1 << BUTTON_RIGHT) | (1 << BUTTON_DOWN) | (1 << BUTTON_LEFT) | (1 << BUTTON_UP) | (1 << BUTTON_SEL);
static Adafruit_seesaw ss;
void onButtonPress() {
Serial.print("Read: ");
Serial.println(ss.digitalReadBulk(s_button_mask), BIN);
}
void setup() {
Serial.begin(115200);
ss.begin(0x49);
ss.pinModeBulk(s_button_mask, INPUT_PULLUP);
ss.setGPIOInterrupts(s_button_mask, true);
pinMode(JOY_IRQ_PIN, INPUT);
Serial.println("Initial read:");
onButtonPress(); // Log initial state
Serial.println("setup() done");
attachInterrupt(JOY_IRQ_PIN, onButtonPress, FALLING);
}
void loop() {
}
For extra debugging, I have built with -DSEESAW_I2C_DEBUG
.
Here's the output when I run the program:
ets Jul 29 2019 12:21:46
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
Begun
Reset
Reading 1 bytes
pos: 1 num:1
Reading 1 bytes
pos: 1 num:1
Done!
Initial read:
Read: Reading 4 bytes
pos: 4 num:4
100011011000000
setup() done
Read: 0
Note that the initial read that happens in setup() shows the expected value. The subsequent read that happens from within the ISR after pressing a button (the final line) shows 0. The ISR fires once, and only once from button presses; any subsequent button presses are ignored. I've further confirmed that the ISR will fire if I short GPIO 14 to + so the ISR should in theory be fine.
I'm guessing at this point the issue has something to do with the ISR context trying to read Seesaw state and something internally not being as expected. The Seesaw API documentation notes that interrupts won't clear until code reads the state, and the fact that the interrupt fires once and only once and doesn't get any result back makes me assume that there's no read actually happening and the internal state doesn't clear. This theory is further bolstered by the debug logging that shows the initial read from setup() getting 4 bytes back while the subsequent read from within the ISR logs nothing.
Arduino board: Nana ESP32 S3
Arduino IDE version (found in Arduino -> About Arduino menu): Version: 2.3.2
Date: 2024-02-20T09:57:46.613Z
CLI Version: 0.35.3
Copyright © 2024 Arduino SA
Compiler responds with the following:
In file included from /private/var/folders/n3/wpnkdym15vv8970_qdlwknvw0000gn/T/.arduinoIDE-unsaved2024215-50002-16ik41b.sypz/LEDArcade_1x4/LEDArcade_1x4.ino:5:
/Users/srosemer/Documents/Arduino/libraries/Adafruit_seesaw_Library/Adafruit_seesaw.h:253:74: error: macro "analogWrite" passed 3 arguments, but takes just 2
virtual void analogWrite(uint8_t pin, uint16_t value, uint8_t width = 8);
^
exit status 1
Hi,
is the SAMD09 Software available open source ?
I can only find the seesaw Arduino IDE library - but not the corresponding microcontroller software.
Or what would also help:
Is it possible to purchase pre-programmed SAMD09 boards identical to the ones built into the Adafruit "NeoKey 1x4 QT I2C" board ?
If yes, what is the price, delivery-time and how do I order ?
If no, is it possible to at least get the source-code of the SMAD09 microcontroller identical to as built into the "NeoKey 1x4 QT I2C" board ?
Thank you for any help on this.
Configuration: HUZZAH32 ESP32 Board + Joy Featherwing "jerryrigged" to the back of a LCD featherwing.
What I expected:
Joystick X and Y data plus buttons saying they've been pressed.
What I got:
Only joystick reports data back, buttons say nothing.
More info:
Possible hardware defect or ESP32 cannot do bitmasks just yet on SDA/SCK?
NeoTrellis.h defines three methods for registering a callback with NeoTrellis and MultiTrellis. The method signatures are such that this does not compile for me using PlatformIO.
A signature such as void registerCallback(uint8_t key, TrellisCallback (*cb)(keyEvent));
Should be rewritten to void registerCallback(uint8_t key, TrellisCallback cb);
And the _callbacks[]
array adjusted to suit.
I wonder how this can compile at all?
I'm not sure how this is happening, and I'm curious if anyone else is able to reproduce this. I'm using the basic example sketch, compiled and uploaded with platformio. I have a kit 4x4 NeoTrellis setup and the trellis connector got disconnected, and execution got hung in trellis.begin()
, so I added a bunch of debug prints and narrowed it down to the delay(10);
on this line:
Adafruit_Seesaw/Adafruit_seesaw.cpp
Line 80 in b2d94a6
It goes through all 10 retries and returns false
just fine after the first call to pixels.begin(...)
here: https://github.com/adafruit/Adafruit_Seesaw/blob/master/Adafruit_NeoTrellis.cpp#L30
But then it hangs on this delay(10)
on the 10th retry when called from Adafruit_seesaw::begin(...)
here: https://github.com/adafruit/Adafruit_Seesaw/blob/master/Adafruit_NeoTrellis.cpp#L32
I put a Serial.printf("before delay, retry %d\n", retries);
before that delay and a Serial.println("After retry loop");
after the loop, and the 9th retry is the last thing that's printed.
Curiously, if I put a Serial.println("After delay");
right after the delay call inside the loop, THEN execution continues and the function returns! Which seems crazy.
Maybe this is some quirk with the vTaskDelay
call in delay()
?
The version in library.properties is still set to 1.0.1
This is a minor issue and may be hardware-dependent. If you call digitalReadBulk()
immediately before calling analogRead()
, the analogRead()
will almost always return 1024. Adding delay(1);
between the commands fixes the issue. In Adafruit_seesaw.cpp, there is a delay at the end of the analogRead()
functions, but not digitalReadBulk()
.
Steps to reproduce:
void loop() {
uint32_t buttons = ss.digitalReadBulk(button_mask);
int x = ss.analogRead(2);
int y = ss.analogRead(3);
....
}
The setBrightness member function in the seesaw_neopixel.cpp file is missing documentation (that is referenced in comments in other sections). Looking at it it looks like it's using a similar but not quite identical technique to the Adafruit_Neopixel library, which has the following documentation:
/*!
@brief Adjust output brightness. Does not immediately affect what's
currently displayed on the LEDs. The next call to show() will
refresh the LEDs at this level.
@param b Brightness setting, 0=minimum (off), 255=brightest.
@note This was intended for one-time use in one's setup() function,
not as an animation effect in itself. Because of the way this
library "pre-multiplies" LED colors in RAM, changing the
brightness is often a "lossy" operation -- what you write to
pixels isn't necessary the same as what you'll read back.
Repeated brightness changes using this function exacerbate the
problem. Smart programs therefore treat the strip as a
write-only resource, maintaining their own state to render each
frame of an animation, not relying on read-modify-write.
*/
void Adafruit_NeoPixel::setBrightness(uint8_t b) {
// Stored brightness value is different than what's passed.
// This simplifies the actual scaling math later, allowing a fast
// 8x8-bit multiply and taking the MSB. 'brightness' is a uint8_t,
// adding 1 here may (intentionally) roll over...so 0 = max brightness
// (color values are interpreted literally; no scaling), 1 = min
// brightness (off), 255 = just below max brightness.
uint8_t newBrightness = b + 1;
In particular, it looks like you don't do the b+1 part, so it would end up with 1=off, brightness increasing to 255, then 0 as the max brightness, and you don't seem to do the rescaling on brightness change.
Hi there,
I'm working on a alt ctrl game using 6 independant NeoTrellis keyboards.
In this project I'm using an arduino nano with 2KB of SRAM.
After a few days I raised multiple segfaults due to collisions between stack and heap.
I optimized my code and now around 500B of RAM are available (still not enought for some usages).
I had a look at the NeoTrellis lib and I found a strange behaviour when I'm initializing neotrellis
The following code using the freeMemory function from here https://learn.adafruit.com/memories-of-an-arduino/measuring-free-memory:
for (int i=0 ; i<6 ; i++) {
Serial.print("Before NeoTrellis init ");Serial.println(freeMemory());delay(10);
this->trellis = new Adafruit_NeoTrellis(addrs[i]);
Serial.print("After NeoTrellis init ");Serial.println(freeMemory());Serial.println();delay(10);
}
is producing the following output:
Before NeoTrellis init 2295
After NeoTrellis init 1269
Before NeoTrellis init 1203
After NeoTrellis init 1130
Before NeoTrellis init 1064
After NeoTrellis init 991
Before NeoTrellis init 925
After NeoTrellis init 852
Before NeoTrellis init 786
After NeoTrellis init 713
Before NeoTrellis init 647
After NeoTrellis init 574
As you can see there is a huge RAM consumption when I created the first object (around 1KB) but small ones for the other objects (~75B).
I tried to find the source of the 1KB consumption but I'm in a dead end for now.
Do you have any idea of what causes this huge memory allocation ?
In case you need it, my full code is here (init in the class def cube.cpp):
https://github.com/yoann-dufresne/project-3
And here is a picture of the controler (for curious people :) ):
https://photos.app.goo.gl/YSnD6Wnm1GGsG3nm8
Hello,
I'm facing an issue, and I am not able to find if it's an hardware or software error.
I'm using the Adafruit_MultiTrellis class with the basic multitrellis example, and some times when I push the button number 0x18, events for buttons 0x0, 0x8, 0x10 and 0x18 are raised, such as I pushed the four buttons at the same time. The order seems to be always the same. It's not happening every time, but nearly one in ten. However, I think it only happens if button 0x0, 0x8 and 0x10 were previously pushed. Right know, I was not able to have a deterministic error.
I have no clue on how to solve that problem.
Hi!
Could it be possible to add some information on how to dim the backlight on the 1.8" TFT shield v2?
Thanks!
Martin
We received feedback asking for an explanation of how to use encoder.getEncoderDelta
. It may be worth including an example in the library that demonstrates use.
Using basic (momentary button) sketch with 1 neotrellis board, if I press 2 buttons, most times one of the leds stays on
Arduino board: Arduino Zero
Arduino IDE version (found in Arduino -> About Arduino menu): 1.8.13
Code uploaded as per: https://learn.adafruit.com/adafruit-i2c-qt-rotary-encoder/arduino
`/*
int32_t getEncoderPosition();
int32_t getEncoderDelta();
void enableEncoderInterrupt();
void disableEncoderInterrupt();
void setEncoderPosition(int32_t pos);
*/
#include "Adafruit_seesaw.h"
#include <seesaw_neopixel.h>
#define SS_SWITCH 24
#define SS_NEOPIX 6
#define SEESAW_ADDR 0x36
#define Serial SerialUSB
Adafruit_seesaw ss;
seesaw_NeoPixel sspixel = seesaw_NeoPixel(1, SS_NEOPIX, NEO_GRB + NEO_KHZ800);
int32_t encoder_position;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println("Looking for seesaw!");
if (! ss.begin(SEESAW_ADDR) || ! sspixel.begin(SEESAW_ADDR)) {
Serial.println("Couldn't find seesaw on default address");
while(1) delay(10);
}
Serial.println("seesaw started");
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
if (version != 4991){
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 4991");
// set not so bright!
sspixel.setBrightness(20);
sspixel.show();
// use a pin for the built in encoder switch
ss.pinMode(SS_SWITCH, INPUT_PULLUP);
// get starting position
encoder_position = ss.getEncoderPosition();
Serial.println("Turning on interrupts");
delay(10);
ss.setGPIOInterrupts((uint32_t)1 << SS_SWITCH, 1);
ss.enableEncoderInterrupt();
}
void loop() {
if (! ss.digitalRead(SS_SWITCH)) {
Serial.println("Button pressed!");
}
int32_t new_position = ss.getEncoderPosition();
// did we move arounde?
if (encoder_position != new_position) {
Serial.println(new_position); // display new position
// change the neopixel color
sspixel.setPixelColor(0, Wheel(new_position & 0xFF));
sspixel.show();
encoder_position = new_position; // and save for next round
}
// don't overwhelm serial port
delay(10);
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return sspixel.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return sspixel.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return sspixel.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}`
I get no neopixel or rotary encoder response. Only button presses. Can you please advise as I have brought three of these modules..
Thanks
I saw in the repo that there is a functionality and even an example to use an encoder, but I cannot find how I can specify the Pins (A and B). I have a Seesaw breakout module. Could anyone point me to how to set the pins?
feather M4 on crickit. Circuitpython.
`import time
from adafruit_crickit import crickit
from adafruit_seesaw.neopixel import NeoPixel
num_pixels = 20
pixels - NeoPixel(crickit.seesaw, 20, num_pixels, brightness=0.2)`
Whatever I set the brightness to it runs at full brightness. The playground express on the crickit does work just fine. I'm following the guide "Make It Glow With Crickit". The guide also has brightness set for the circuit playground example but not on the feather example.
Arduino board: RP2040 Feather + miniTFTwing
Arduino IDE version (found in Arduino -> About Arduino menu): 1.18.13
List the steps to reproduce the problem below (if possible attach a sketch or
copy the sketch code in too):
The root cause appears to be that the RP2040 documentation implies that the Feather header SDA/SCL pins are attached to I2C port 0 (Wire/Wire0) and the Qwiic connector is on I2C port 1 (Wire1), where in reality they're both connected to port 1.
This issue has also been reported to the Arduino Pico project: earlephilhower/arduino-pico#1465
Arduino board: Arduino zero
Arduino IDE version (found in Arduino -> About Arduino menu): 2.0
INPUT_PULLUP doesn't seem to be implemented for the ATtiny817 on Arduino, but has been implemented on python.
https://learn.adafruit.com/adafruit-attiny817-seesaw/digital-input
Is there an update coming?
Cheers
It would be nice if there was an example of using setGPIOInterrupts
with attachInterrupt
. The existing interrupt examples seem to be slightly misleading in suggesting that you can properly test for interrupts by watching for a LOW
signal on a local pin that's been connected to the IRQ output on the SeeSaw module. However, what is properly needed is some code that can use attachInterrupt
to detecting a FALLING
signal instead.
The NeoTrellis INT line occasionally getting stuck low issue.
I created a very simple reproduce case that is documented below:
This bug report was originally posted on the adafruit forum which included some pictures
https://forums.adafruit.com/viewtopic.php?f=22&t=192463
Hope this is helpful,
Louie
p.s. i have 13 of these neotrellis boards.
p.s. there is a workaround...detect when the INT line is stuck low and call NeoTrellis.SWReset()
p.s. i think Adafruit is awesome. I am very happy Adafruit customer. Your sw libraries make building so easy.
I receive an error, when compiling with...
#define USE_OLED true
The error message is...
Arduino: 1.8.16 (Mac OS X), Board: "Adafruit Feather M4 Express (SAMD51), Enabled, 120 MHz (standard), Small (-Os) (standard), 50 MHz (standard), Arduino, Off"
multiple_encoders:16:59: error: invalid cast to abstract class type 'Adafruit_SH110X'
16 | Adafruit_SH110X display = Adafruit_SH110X(64, 128, &Wire);
Replacing...
Adafruit_SH110X display = Adafruit_SH110X(64, 128, &Wire);
With....
Adafruit_SH1107 display = Adafruit_SH1107(64, 128, &Wire);
Compiles successfully.
I buy this 4 encoders board, to use with an ESP32 who have all pins busy with parallel TFT display
when I use your example
"#define SS_SWITCH 24
#define SS_NEOPIX 6
#define SEESAW_ADDR 0x49",
#define...PIN_A .... ??????????
#define...PIN_B .... ??????????
this block my display because ESP32 take HIS 24 and 6 pin,
not from I2C board; and how to declare the PIN A and PIN B ??
how can I define to be ok ??
please made an example how to use your library with ESP..
Arduino: 1.8.5 (Linux), Board: "Arduino/Genuino Uno"
/home/user/Arduino/libraries/Adafruit_seesaw_Library/examples/TFTShield18/shieldtest/shieldtest.ino: In function 'void bmpDraw(char*, uint8_t, uint8_t)':
shieldtest:235: error: 'class Adafruit_ST7735' has no member named 'Color565'
tft.pushColor(tft.Color565(r,g,b));
^
Adafruit_ST7735 -> Adafruit_ST77xx -> Adafruit_SPITFT
Just a case issue?
https://github.com/adafruit/Adafruit-GFX-Library/blob/master/Adafruit_SPITFT.h#L87
add &Wire argument to initializer
RP2040 feathers seem to use Wire1 for the standard I2C pins, so we need to be able to specify Wire1
Required to fix adafruit/Adafruit-ST7735-Library#185
BUG: Adafruit_seesaw.cpp appears to have a bug in that the chip is not identified in the Adafruit_seesaw::setPWMFreq
function, and so legit pins can not have their PWM frequency set; the call is prematurely returned.
SOLUTION: The setPWMFreq
function should look like the analogWrite
function which tests each Hardware ID Code to determine which pins support PWM per chip. I think it should look a bit like this:
int8_t p = -1;
if (_hardwaretype == SEESAW_HW_ID_CODE_SAMD09) {
switch (pin) {
case PWM_0_PIN:
p = 0;
break;
case PWM_1_PIN:
p = 1;
break;
case PWM_2_PIN:
p = 2;
break;
case PWM_3_PIN:
p = 3;
break;
default:
#ifdef SEESAW_I2C_DEBUG
Serial.printf("SEESAW: PWM not supported on Pin %d for hardware %d\n", pin, _hardwaretype);
#endif
break;
}
} else {
p = pin;
}
It only clears the local state, not the buffer on the seesaw.
The code only memsets the local buffer:
Adafruit_Seesaw/seesaw_neopixel.cpp
Line 287 in ddd6956
And there does not appear to be any command on the seesaw to actually clear it either:
https://github.com/adafruit/seesaw/blob/ad471bd26fd5ddb4b320dafd0275e58e5f052714/include/event.h#L118
What is the best way to clear all pixels?
Looping all pixels and calling setPixelColor
seems inefficient.
Can we use NEOPIXEL_SET_BUFFER_REQ
to set all pixels to 0 at once?
Hy
I really like your products and have a lot of them.
But unfortunately, there is a problem at the attiny1616 (together with Arduino Nano 33 BLE):
when trying the blink example --> error, seesaw not found
I2C scanner: no device found
when I do exactly the same with a Seeeduino Xiao, both works (scanner and blink demo)
when I scan on the Nano 33 BLE on Wire1, 2x I2C sensors on the Arduino Nano 33 BLE are shown with address
when I scan with the Nano for the sparkfun BME680, it works, too.
when I scan with the Nano for your Stemma GPS-module, addresse 0x10 is shown, too.
Just the seesaw Attiny1616 is not detected.
I hope you find a solution before the weekend.
Thanks and kind regards
Silvan
Looks like this library is using BusIO:
Adafruit_Seesaw/Adafruit_seesaw.h
Line 24 in 4d72e3d
Adafruit_Seesaw/Adafruit_seesaw.h
Line 26 in 4d72e3d
Adafruit BusIO
listed as a dependency:Adafruit_Seesaw/library.properties
Line 10 in 4d72e3d
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.